【发布时间】:2019-05-26 12:18:54
【问题描述】:
我是 Java 新手,我试图通过模拟以下程序来了解当我将子类实例分配给父类实例变量时会发生什么。
public class ConfusionWithInheritance {
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
DerievedClass d = new DerievedClass();
BaseClass b = BaseClass.class.cast(d);
BaseClass b1 = new DerievedClass();
b.doSomeJob();
b.printMagic(); //-> Compiler shouted me that it didn't know this method here.
}
}
class BaseClass {
public void doSomeJob() {
System.out.println("Printing Value X");
}
}
class DerievedClass extends BaseClass {
public void doSomeJob() {
System.out.println("Printing Value Y");
}
public void printMagic() {
System.out.println("Printing magic...");
}
}
1) 为什么允许我将子类的实例分配给父类型变量?
2) 从这个answer 可以解释,因为我告诉蓝图类的蓝图是——父类——它只知道父类中的方法。那为什么我在调用 childInstance.doSomeJob() 的时候会在子类的方法中打印值呢?
【问题讨论】:
-
如果您添加
@Override public void doSomeJob() {并看到您被允许这样做,第二个答案就会变得清晰。而如果你使用其他方法,你会得到一个编译器错误。 -
没有充分的理由写
SomeClass.class.cast(d):(SomeClass) d更简洁,并提供更多的编译时检查。 -
Animal a = new Dog();。Dog是Animal。因此,您可以将其分配给这样的变量是有道理的。将变量与实例区分开来。该变量仍然指的是实际的狗。只是变量说“嘿,我可以引用所有动物”。尽管该实例是一条狗并且从技术上讲a.bark()可以工作,但Java 可以保护您免受这种情况的影响。既然你可以做a = new Cat(),那么它就不再起作用了。可以通过 casting((Dog) a).bark()检索类型信息。虽然这通常突出了一个糟糕的设计。
标签: java inheritance single-inheritance