java - 为什么 Java 不允许我执行这种类型的多态性/继承?

标签 java inheritance polymorphism

我正在重构一个巨大的 if 语句。我发现改进它的方法之一是使用多态性和继承。以一种非常简单的方式,这就是我的代码中的内容:

public abstract class Animal {  
    public abstract void doAction();  
}

public class Dog extends Animal {  
    public void doAction() {System.out.println("run");} 
}

public class Cat extends Animal {  
    public void doAction() {System.out.println("sleep");}
}

public class RunActions {  
    public void runAction(Dog d) {
        d.doAction();
    }

    public void runAction(Cat c) {
        c.doAction();
    }
}

public class Start {
    public static void main(String args[]) {
        Animal animal = new Dog();
        new RunActions().runAction(animal); // Problem!
    }
}

我知道,我知道。我可以直接调用animal.doAction();。或者在 RunActions 中添加一个接收 Animal 作为参数的方法。

但是为什么编译器不允许我调用最后一个“runAction(animal)”行? JVM 不应该在运行时识别出 Animal 是 Dog 的实例吗?

有什么具体原因不允许我这样做吗?

编辑:忘记让 Dog 和 Cat 扩展 Animal。已修复。

最佳答案

编译器无法保证运行时有合适的方法。

您有一个采用 Cat 的方法,并且有一个采用 Dog 的方法。您正在尝试传递引用 DogAnimal 变量。如果引用大象怎么办?那么运行时就没有合适的方法了。这就是为什么它不会让你编译。

Animal animal = new Elephant();
new RunActions().runAction(animal); // real problem now!

关于java - 为什么 Java 不允许我执行这种类型的多态性/继承?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16898040/

相关文章:

java - 如何使 <T extends E> 包含泛型类型参数?

c# - 防止 C# 子类覆盖方法

java - java变量的多态或改名

c# - 从父类继承而无需重新实现父类的子类接口(interface)

java - intern() 在 Java 6 和 Java 7 中的行为不同

java - 野蝇会杀死另一只野蝇吗?

java - Issue detecting PCSCvia program on linux, 读卡器已连接

c# - 无法在 C# 中创建两个具有相同名称的属性

c++ - 在 C++ 中描述什么是虚函数的最简洁但准确的方法是什么?

java - Recyclerview 适配器中的空指针异常