0
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 中它的行为是对Print2-object 的引用?

  2. 为什么在 Call 2print(B b)中被调用Print2而不是print(C c)

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

4

2 回答 2

0

由于可变阴影,第一次打印按预期工作。

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

如果您将另一个变量添加int yPrint1类中,则不会那么混乱。您可以System.out.println(p1.y);毫无问题地访问它。


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

由于print(c)方法是在对象上执行的,因此对象显然是类型的Print2(无论变量类型是(Print1Print2),您将使用Print2' 方法。仅仅是因为Print2' 方法覆盖了Print1' 方法。

于 2015-08-05T14:14:54.163 回答
0

变量的类型用于确定访问的类成员。

因此p1.x是指x领域中Print1,而不是一中Print2。(如果您x从中删除,则会导致编译时错误Print1。) 中的x字段Print2是不同的字段,即Print2对象有 2 个不同的int字段。

由于没有print(B b)方法,因此在表达式中也使用了方法。(这将是一个编译时错误,如果不会扩展或。)由于覆盖 的实现,因此使用该实现。p1.print(c)Print1print(C c)CBAPrint2Print1.print(B b)

于 2015-08-05T14:35:39.123 回答