超类引用无法在 Java 中调用子类方法 [英] Superclass reference not able to call subclass method in Java

查看:34
本文介绍了超类引用无法在 Java 中调用子类方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对 Java 中的多态性有一个基本的怀疑.我在一个名为 AnimalTestDrive.java 的文件中编写了以下代码.根据我的说法,下面的代码应该特别适用于粗体行,但不幸的是它不是.你能解释一下原因吗,我给出了以下错误:

I have a basic doubt in polymorphism in Java. I have written the code below in one file named AnimalTestDrive.java. According to me the code below should work specially the line in bold but unfortunately its not. Can you please explain why, I have given the error below:

class Dog extends Animal {

    public void dogMethod() {
        System.out.println("In Dog method");
    }
}

public class AnimalTestDrive {
    public static void main(String args[]) {
        Dog d = new Dog();
        d.dogMethod();
        d.animalMethod();

        Animal animal = new Animal();
        animal.animalMethod();

        animal = d;
        **animal.dogMethod(); // THIS IS NOT WORKING**

    }
}

推荐答案

让我们试着像编译器一样看待这一行:

Let's try to look at this line the same way that the compiler would:

animal.dogMethod();

首先,它需要弄清楚animal 是什么意思.这很好也很简单——它是当前方法中的一个局部变量,所以不需要看得太远.

First, it needs to work out what animal means. That's nice and easy - it's a local variable in the current method, so it doesn't need to look far.

该变量的编译时类型是 Animal.编译器不关心变量在执行时的是什么——它只使用有关声明类型的信息.

The compile-time type of that variable is Animal. The compiler doesn't care what the value of the variable will be at execution time - it only uses the information about the declared type.

所以,这就是它用来尝试在 animal 的上下文中查找 dogMethod() 含义的方法,即类型为 Animal.首先在 Animal 中查找,然后在 java.lang.Object(Animal 的隐式超类)中查找 - 但这些类都不包含声明dogMethod.那时,编译器不得不放弃一个错误——它找不到方法.该方法在 animal 引用的值的对象的 执行时间 类型上是否可用并不重要.它必须在编译时绑定它,只使用编译时可用的信息.

So, that's what it uses to try to look up what dogMethod() means within the context of animal, i.e. with type Animal. First it looks in Animal, then in java.lang.Object (the implicit superclass of Animal) - but neither of those classes contains a declaration of dogMethod. At that point, the compiler has to give up with an error - it can't find the method. It doesn't matter that the method is available on the execution-time type of the object that the value that animal refers to. It has to bind it at compile-time, using only the information available at compile time.

执行时做出的唯一决定是使用方法的哪个实现 - 例如,如果您调用了 animal.toString()Dog 类有一个覆盖,例如

The only decision made at execution time is which implementation of a method is used - for example, if you called animal.toString() and the Dog class had an override, e.g.

@Override public String toString() {
    return "I'm a dog";
}

然后编译器会从 java.lang.Object 中找到 toString() 方法,所以它会知道方法调用是有效的 - 但是 由于对象的执行时间类型,将使用 Dog 中的实现.

then the compiler would find the toString() method from java.lang.Object, so it would know that the method call was valid - but the implementation in Dog would be used because of the execution-time type of the object.

这篇关于超类引用无法在 Java 中调用子类方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆