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

Why doesn't Java allow me to perform this type of polymorphism/inheritance?

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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();。或者在"失控"中添加将动物作为参数接收的方法。

但是为什么编译器不允许我称最后一行为"逃跑(动物)"?JVM不应该在运行时发现animal是dog的一个实例吗?

有没有具体的理由不允许我这么做?

编辑:忘记让狗和猫延伸动物。固定的。


编译器不能保证the method that there is an在适当的运行。P></

You have a method that have a Cat需要你需要Dogmethod that。你是想在西安Animal变通,Dogreferences。如果我安Elephant参考?我有法不适用于在运行时会好的。这就是为什么它不会让你的编译。P></

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


that makes the main基础概念是不可能是你想要的是,Java语言类单调度到其他语言,我几乎只是"面向对象"。this is that the means是什么需要运行决策method to which the first call into帐户只method which argument is before the placed,语法点,正如一个value to the will be拓展this特殊变量。P></

你可能也知道为什么单身is used in languages DISPATCH most…This has to do with the Basic和对象是业主的想法of of their胶囊成囊的方法。考虑你的房子应该属于RunActionsor to:runActionAnimal?belongs to both equally恩;恩:更好的stated to或者不属于。completely different about this brings编程模型在一个胶囊成囊,没有。P></


is not the问题可能是猫或狗的动物。考虑:P></

1
2
3
public class Fish implements Animal{  
    public void doAction() {System.out.println("swim");  
}

什么你会期望你的runactions class to do?P></

这就是为什么complaining is the编译器。P></

是有一些方法,你可以让你的工作使用的情况。the method that is to have one扩使用一系列accepts动物和人物instanceof检验学院是你想出来的特异性subclass with each of给动物。P></


在第一局,布尔AnimalDogCatshould extendP></

1
2
3
4
public class Dog exttends Animal{  
    @Override
    public void doAction() {System.out.println("run");  
}

与使用:P></

1
2
3
4
5
public class RunActions {  
    public void runAction(Animal a) {
        a.doAction();
    }
}

Dog和AS都是AnimalsCatAnimalargument,你可以使用。P></


导致更好的给你P></

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public interface Animal {  
    public void doAction();  
}

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

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

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

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


首先,你是不是在狗和猫伸展的动物。我给你我的第一。P></

在ISA委托继承得到3年的随访。P></

我知道for exampleP></

1
public class Dog extends Animal

我的狗在狗的动物,动物extends is is not true but the逆向cannot be necessarily动物狗。它也可以在你家的猫。P></

我知道当你的通行证参考动物to the method of which accepts在狗或猫的摇篮配置something likeP></

1
Dog d=animal;

which is read as is that is not动物狗和真。P></

Will not allow编译器知道你给我。P></

为什么不允许和对Java is to that thing to be done that is the features是capable of achieving EN。P></

说你allows for example,Java对象通动物allows to the method and execute the method to You。P></

我知道在我的房子P></

1
2
3
Animal animal=new Dog();
Dog d= animal;
d.doSomething(); // let's say java allowed this no problem since animal is DOG.

但是,P></

1
2
3
Animal animal=new Horse();
Dog d= animal;
d.doSomething(); // Can you imagine what will happen in this case?

我知道这样的situaltion Java智能avoid is to You are to停止当你已经做了。希望这帮助你和你的clears了解这发生。P></