【发布时间】:2017-12-01 09:51:26
【问题描述】:
据我了解,根据我对运行时间polymorphism 的了解,以下代码应打印a。
但是,当我运行以下代码时,它正在打印 b:
根据 JLS 8.4.8.1,B1.m1 不会覆盖 A1.m1,因此当 A1.m1 是 调用时,不应选择 B1.m1
package a;
public interface I1 {
public Object m1();
}
public class A1 {
Object m1() {
return "a";
}
}
public class C1 extends b.B1 implements I1 {
public static void main(String[] args) {
a.A1 a = new a.C1();
System.out.println(a.m1());
}
}
package b;
public class B1 extends a.A1 {
public String m1() {
return "b";
}
}
谁能帮我理解这种行为。
【问题讨论】:
-
在 java 中,超类中的方法不会在被覆盖的方法之前自动调用。但是超类中的构造函数在被覆盖的构造函数之前被调用。
-
Test1类从B1继承m1方法。因此,如果您在任何Test1对象上调用m1,它将打印"b"。如果你说new Test1(),那么你已经创建了一个Test1对象,所以它将打印b。变量a被声明为A1并不重要——它所引用的对象仍然是Test1。所有A1说的是a可以是对类A1或子类的any 对象的引用。它不会改变实际对象的类型。 -
只看它,它看起来应该打印
b。为什么你认为它应该打印a? -
a的真实类型不是A1,而是Test1(继承自B1) -
为什么这么多的cmets和答案都参考你的原始代码,你为什么要把代码从
Test1改为C1?现在很难阅读或理解。
标签: java