我正在阅读一本Java教科书,遇到了一个疑问。 父类(super class)的引用变量可以被分配对从该父类(super class)派生的任何子类的对象的引用。但是,当对子类对象的引用分配给父类(super class)引用变量时,您将只能访问由父类(super class)定义的对象的那些部分。 示例:
class X {
int a;
X(int i) {
a = i;
}
}
class Y extends X {
int b;
Y(int i, int j) {
super(j);
b = i;
}
}
class SupSubRef {
public static void main(String args[]) {
X x = new X(10);
X x2;
Y y = new Y(5, 6);
x2 = x; // OK, both of same type
System.out.println("x2.a: " + x2.a);
x2 = y; // still Ok because Y is derived from X
System.out.println("x2.a: " + x2.a);
// X references know only about X members
x2.a = 19; // OK
// x2.b = 27; // Error, X doesn't have a b member
}
}
因此,在上面的示例中,x2(父类(super class)类型的变量)可以引用派生类的对象,但它不能访问子类特定的成员。然而,在关于方法重写的讨论中,表明父类(super class)引用变量对重写方法的调用可以解析为子类方法。但是子类方法并没有在父类(super class)中定义,那么这不是矛盾吗,父类(super class)引用变量怎么能够访问子类具体方法呢?示例:
class Sup {
void who() {
System.out.println("who() in Sup");
}
}
class Sub1 extends Sup {
void who() {
System.out.println("who() in Sub1");
}
}
class Sub2 extends Sup {
void who() {
System.out.println("who() in Sub2");
}
}
class DynDispDemo {
public static void main(String args[]) {
Sup superOb = new Sup();
Sub1 subOb1 = new Sub1();
Sub2 subOb2 = new Sub2();
Sup supRef;
supRef = superOb;
supRef.who();
supRef = subOb1;
supRef.who();
supRef = subOb2;
supRef.who();
}
}
程序的输出如下所示:
who() in Sup
who() in Sub1
who() in Sub2
那么supRef是如何访问子类对象中的who方法的呢?
最佳答案
当教科书说您无法使用 x2
访问特定于子类的成员时,这意味着您无法在编译时访问它们。
给编译器。 x2
是 X
类型(尽管在运行时它实际上是 Y
类型),所以当编译器看到你时尝试访问 Y
中定义的内容时,它发现并说“那不是在 X
中定义的。你不能这样做!”
但是,我们都知道,在运行时,x2
存储对 Y
对象的引用。在运行时,您确实可以使用 x2
访问 Y
中定义的成员。您可以使用反射来证明这一点。
在运行时,x2
的类型为 Y
,因此显然会调用 Y
的实现。
关于java - 通过父类(super class)引用变量访问子类成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47897536/