当前位置: 首页 > 知识库问答 >
问题:

超类引用不应该能够调用其子类专用的方法,但是

鄢英毅
2023-03-14

但是,如果超类有一个抽象方法,并且该方法是在它的子类中实现的,这是具体的,那么我们仍然能够使用超类的对象调用子类的方法实现。

怎么会?

对于重载方法也是一样,即使使用超类的引用调用子类,也会调用它的实现。

让我在这里更具体一点。。。

假设动物是一个超类,狗是一个子类。现在,我确实:

Animal a = new Dog();

这意味着a是指动物类,对吗?

现在,如果我这样做了,a.function();(假设函数在动物中定义,在狗中覆盖),动物的版本应该被称为是对动物的引用,但事实正好相反。

共有1个答案

东方权
2023-03-14

这意味着超类不能调用在子类中定义的方法,因为超类不知道这些方法。对于抽象方法,超类知道它们,因此可以调用它们。非抽象和非最终方法也会发生这种情况:它们可以由子类修改,而不必注意到超类,而且超类仍然可以正常工作。

您所描述的是编译时间和执行时间(也称为运行时间)之间的区别。在编译时,变量只能调用在变量声明的类型上定义的方法,例如动物,然后动物变量只能调用在动物类中定义的方法。在执行时,方法的执行将由属于对象引用实例的类处理,例如动物=新狗();然后动物行为将由类中声明的行为定义。

例子:

public class Animal {
    abstract void breath();
}

public class Dog extends Animal {
    @Override
    public void breath() {
        System.out.println("Dog breathing");
    }

    public void bark() {
        System.out.println("woof!");
    }
}

public class Client {
    public static void main(String[] args) {
        //animal variable is of type Animal
        //and initialized as a Dog object reference
        Animal animal = new Dog();

        //dog variable is of type Dog (also an Animal)
        //and initialized as a Dog object reference
        Dog dog = new Dog();

        animal.breath();
        dog.breath();

        //line below throws a compiler exception
        //since animal is declared as type Animal
        //not all Animals know how to bark
        animal.bark();

        //line below compiles fine
        //since dog is declared as type Dog
        //and Dog's know how to bark
        dog.bark();
    }
}

 类似资料:
  • 问题内容: 我有这样的代码: 为什么我不能在第(5)行中打电话;在第(6)行中将为哪个类调用? 问题答案: 您不能这样做,因为子类的方法不在您的超类中。在这种情况下,尽管String是Object的子类,因为在java.lang.Object类中未声明length(),但无法在其实例上调用length。 但是equals()方法在字符串类中被覆盖,因此将调用Strings的equals()

  • 问题内容: 让我们看一下这段代码: 我希望这能打印出“孩子”,但结果是“父母”。为什么Java会改为调用父类,我该怎么做才能使其在子类中调用方法? 问题答案: 不会覆盖,因为它没有相同的形式参数。一个拿走,另一个拿走。因此,运行时的多态不会被应用,并且不会导致子类方法的执行。根据Java语言规范: 如果满足以下所有条件,则在类C中声明或由类C继承的实例方法从类C中 重写 另一个在类A中声明的方法:

  • 问题内容: 我对Java中的多态性有基本的疑问。我已经在一个名为AnimalTestDrive.java的文件中编写了以下代码。根据我的说法,以下代码应专门以粗体显示该行,但不幸的是,它不能。您能否解释为什么,我给出了以下错误: 问题答案: 让我们尝试以与编译器相同的方式查看此行: 首先,它需要弄清楚是什么意思。很好而且很容易-它是当前方法中的局部变量,因此它不需要花很多时间。 该变量的编译时类型

  • 我正在学习java入门课程,我们刚刚开始学习继承。我正在做一项任务,要求我们创建一个具有名称和年龄的“Pet”超类;和三个子类,每个都有自己独特的特征(我选择了“狗”、“猫”和“鸟”)。在我们构建了所有这些之后,我们将创建一个主类来测试一切,这就是我遇到问题的地方。我试图为这些独特的特性调用

  • 问题内容: 我正在学习Java入门课程,我们才刚刚开始学习继承。我正在完成一项任务,要求我们创建一个具有名称和年龄的“宠物”超类。和三个子类,每个子类都有自己的独特特征(我选择了“狗”,“猫”和“鸟”)。构建完所有这些之后,我们将创建一个Main类来测试所有内容,这就是我遇到问题的地方。我试图在中调用这些独特特征的方法,但似乎只能找到超类中的方法。 这是主类: 这是我的超人 这是子类之一(它们看起

  • 我在学习Java,同时试图理解继承。我不明白为什么子类walk()中重写的方法执行了,而另一个xyz()方法却没有执行。 我的问题是,如果下面的方法调用工作正常,并调用士兵方法walk,