java - 通过父类(super class)引用变量访问子类成员

标签 java inheritance overriding

我正在阅读一本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 访问特定于子类的成员时,这意味着您无法在编译时访问它们。

给编译器。 x2X 类型(尽管在运行时它实际上是 Y 类型),所以当编译器看到你时尝试访问 Y 中定义的内容时,它发现并说“那不是在 X 中定义的。你不能这样做!”

但是,我们都知道,在运行时,x2 存储对 Y 对象的引用。在运行时,您确实可以使用 x2 访问 Y 中定义的成员。您可以使用反射来证明这一点。

在运行时,x2 的类型为 Y,因此显然会调用 Y 的实现。

关于java - 通过父类(super class)引用变量访问子类成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47897536/

相关文章:

java - 将 jaudiotagger 导入到 eclipse

java - 如何在计时器内绘制 2D 对象

Java Servlet 上传一个文件到多个文件夹

java - 代码返回节点而不是子类的值

c++ - 虚运算符重载 C++

java - 没有类型转换的Java编译器如何在子类中调用正确的equals()函数?

Javascript 覆盖问题类 xml

java - xml命名空间到java,如何建模 'choice'?

jquery - 如何在不修改 jquery.validate.unobtrusive.min.js 的情况下重写 JQuery unobtrusive 方法?

c++ - 从覆盖函数调用覆盖函数