用Java绑定(覆盖方法和“字段”)

时间:2015-08-05 14:11:07

标签: java dynamic-binding static-binding

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的子类。

  1. 为什么在类型为P1的调用1 Print1中,即使它引用类型为Print2的对象,而在调用2中,它也表现为对{{1}的引用} -object?

  2. 为什么拨打电话2 Print2来自print(B b)而不是Print2

  3. 到目前为止,这对我来说是最令人困惑的事情。谢谢您的帮助。

2 个答案:

答案 0 :(得分:0)

由于变量阴影,首次打印按预期工作。

您有一个变量p1(类型Print1)指向类型为Print2的堆上的对象。由于Print2继承自Print1,因此这是允许的。并且您可以访问x的变量Print1,因为变量没有多态性,它们不能相互“覆盖”。您的变量类型确定了您想要获取的x

如果要将另一个变量int y添加到Print1类,那就不那么容易混淆了。您可以毫无问题地将其作为System.out.println(p1.y);访问。

由于多态(通过继承),第二个也按预期工作。

由于对对象执行print(c)方法,该对象显然属于Print2类型(无论变量类型是什么(Print1Print2),你将使用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不会扩展APrint2,那将是编译时错误。)由于Print1.print(B b)会覆盖sizeToFit的实现,因此该实现使用。