public class Print1 {
int x = 1;
public void print(A a) { System.out.println(x); }
public void print(B b) { System.out.println(x+1); }
}
public class Print2 extends Print1 {
int x = 3;
public void print(A a) { System.out.println(x); }
public void print(B b) { System.out.println(x+1); }
public void print(C c) { System.out.println(x+2); }
}
// a tester class with main method
A a = new A(); B b = new B(); C c = new C();
Print1 p1 = new Print1();
Print2 p2 = new Print2();
p1 = p2;
System.out.println(p1.x); // Call 1, p1 is from Type Print1
p1.print(c); /* Call 2
//p1 is from Type Print2, print(B b) will be called */`
B类是A类的子类,C是B的子类。
为什么在类型为P1
的调用1 Print1
中,即使它引用类型为Print2
的对象,而在调用2中,它也表现为对{{1}的引用} -object?
为什么拨打电话2 Print2
来自print(B b)
而不是Print2
?
到目前为止,这对我来说是最令人困惑的事情。谢谢您的帮助。
答案 0 :(得分:0)
由于变量阴影,首次打印按预期工作。
您有一个变量p1
(类型Print1
)指向类型为Print2
的堆上的对象。由于Print2
继承自Print1
,因此这是允许的。并且您可以访问x
的变量Print1
,因为变量没有多态性,它们不能相互“覆盖”。您的变量类型确定了您想要获取的x
。
如果要将另一个变量int y
添加到Print1
类,那就不那么容易混淆了。您可以毫无问题地将其作为System.out.println(p1.y);
访问。
由于多态(通过继承),第二个也按预期工作。
由于对对象执行print(c)
方法,该对象显然属于Print2
类型(无论变量类型是什么(Print1
或Print2
),你将使用Print2
的方法。只是因为Print2
的方法已经覆盖了Print1
的方法。
答案 1 :(得分:0)
类型的变量用于确定被访问的类成员。
因此p1.x
引用x
中的Print1
字段,而不是Print2
中的x
字段。 (如果您从Print1
删除x
,则会导致编译时错误。)Print2
中的Print2
字段是不同的字段,即int
对象有2个不同的print(B b)
字段。
此外,p1.print(c)
方法用于表达式Print1
,因为print(C c)
没有方法C
。 (如果B
不会扩展A
或Print2
,那将是编译时错误。)由于Print1.print(B b)
会覆盖sizeToFit
的实现,因此该实现使用。