在 Java 中绑定(覆盖方法和 "fields")
Binding in Java (overriding methods and "fields")
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 */`
Class B 是 Class A 的子类,C 是 B 的子类。
为什么在类型 Print1
的调用 1 P1
中,即使它引用的是类型 Print2
的对象,而在调用 2 中它的行为是对Print2
-对象?
为什么调用 2 print(B b)
是从 Print2
而不是 print(C c)
调用的?
这是迄今为止 Java 中让我最困惑的事情。谢谢您的帮助。
由于 可变阴影,首次打印如预期工作。
您有一个变量 p1
(类型 Print1
)指向堆上类型 Print2
的对象。因为 Print2
继承自 Print1
这是允许的。并且您能够访问 Print1
的变量 x
因为变量没有多态性,它们不能彼此 "override" 。您的变量类型决定了您要获取的 x
。
如果您在 Print1
class 中添加另一个变量 int y
会减少混淆。您可以毫无问题地以 System.out.println(p1.y);
访问它。
由于多态性(通过继承),第二个也按预期工作。
因为print(c)
方法是在一个对象上执行的,对象显然是Print2
类型(不管变量类型是什么(Print1
或Print2
), 您将使用 Print2
的方法。只是因为 Print2
的方法覆盖了 Print1
的方法。
变量的类型用于确定访问的class成员。
因此 p1.x
指的是 Print1
中的 x
字段,而不是 Print2
中的字段。 (如果从 Print1
中删除 x
,将导致编译时错误。)Print2
中的 x
字段是不同的字段,即 Print2
对象有 2 个不同的 int
字段。
在表达式 p1.print(c)
中也使用了 print(B b)
方法,因为 Print1
没有方法 print(C c)
。 (如果 C
不会扩展 B
或 A
,这将是一个编译时错误。)由于 Print2
覆盖了 Print1.print(B b)
的实现,该实现被使用了。
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 */`
Class B 是 Class A 的子类,C 是 B 的子类。
为什么在类型
Print1
的调用 1P1
中,即使它引用的是类型Print2
的对象,而在调用 2 中它的行为是对Print2
-对象?为什么调用 2
print(B b)
是从Print2
而不是print(C c)
调用的?
这是迄今为止 Java 中让我最困惑的事情。谢谢您的帮助。
由于 可变阴影,首次打印如预期工作。
您有一个变量 p1
(类型 Print1
)指向堆上类型 Print2
的对象。因为 Print2
继承自 Print1
这是允许的。并且您能够访问 Print1
的变量 x
因为变量没有多态性,它们不能彼此 "override" 。您的变量类型决定了您要获取的 x
。
如果您在 Print1
class 中添加另一个变量 int y
会减少混淆。您可以毫无问题地以 System.out.println(p1.y);
访问它。
由于多态性(通过继承),第二个也按预期工作。
因为print(c)
方法是在一个对象上执行的,对象显然是Print2
类型(不管变量类型是什么(Print1
或Print2
), 您将使用 Print2
的方法。只是因为 Print2
的方法覆盖了 Print1
的方法。
变量的类型用于确定访问的class成员。
因此 p1.x
指的是 Print1
中的 x
字段,而不是 Print2
中的字段。 (如果从 Print1
中删除 x
,将导致编译时错误。)Print2
中的 x
字段是不同的字段,即 Print2
对象有 2 个不同的 int
字段。
在表达式 p1.print(c)
中也使用了 print(B b)
方法,因为 Print1
没有方法 print(C c)
。 (如果 C
不会扩展 B
或 A
,这将是一个编译时错误。)由于 Print2
覆盖了 Print1.print(B b)
的实现,该实现被使用了。