超类参考访问澄清

时间:2017-10-14 10:27:57

标签: java inheritance

根据下面的代码,如果超类引用指向子类对象,并且子类已重写超类的方法,则超类引用将始终具有对子类中重写方法的完全访问权限,并且无法访问其他方法的子类。我的假设是否正确?

class ParentClass{

    public void Method(){
        System.out.println("Parent method");
    }

}

public class ChildClass extends ParentClass{

    public void Method(){
        System.out.println("child method");
    }

    public static void main(String[] args) {

        ParentClass obj2 = new ChildClass();

        obj2.Method();

    }

}

3 个答案:

答案 0 :(得分:1)

您拥有的参考的类型是关键。 obj2的类型为ParentClass,因此它只能访问ParentClass定义的界面(包括Method)。在运行时,运行的Method是实际对象obj2引用的被覆盖的ChildClass,它是来自ChildClass的对象。如果ParentClass定义了obj2没有的方法,那么您无法通过obj2引用访问该方法,因为它不属于{{1}类型的一部分(ParentClass)。 (您必须将您的引用转发给ChildClass才能访问它。)

答案 1 :(得分:0)

第1部分

超类引用始终具有对子类

中重写方法的完全访问权限

引用没有访问权限,而是对它的方法调用将定向到子类方法。

由于JLS,方法将始终具有相同或较弱的访问规则,并且还因为Liskov的替换原则。

  

覆盖或隐藏方法的访问修饰符(第6.6节)必须至少提供与被覆盖或隐藏方法一样多的访问权限... Source

第2部分

无法访问子类的其他方法

如果你有一个扩展Y的X实例,在Y类型的变量中你将只能访问X的方法,访问子类方法的唯一方法是将变量强制转换为X

这是因为 Liskov的替换原则,它声明X的实例应该能够在Y的实例所在的地方使用(所以Y的所有方法都应该可用),并且因为Z可以扩展Y,而不使用Xs方法,所以编译器不能确定额外的方法是否可用(因此X中不应提供额外的方法)。

  

Likov的替换原则指出,如果程序模块使用Base类,则可以使用Derived类替换对Base类的引用,而不会影响程序模块的功能。 Source

答案 2 :(得分:0)

是的,你的假设是正确的。
Java允许您从现有类派生新类。 ...用于派生新类的原始类称为超类,父类或基类。派生类是子类或子类。 Java使用关键字extends来表示新类是从超类派生的。

public class A{
    public void method(){
        System.out.println("Hello A");
    }
}

public class B extends A{
    public void method(){
        System.out.println("Hello B");
    }
}

public class Program
{
    public static void main(String[] args) {
        A a= new B();
        a.method();
    }
}

这里你会得到像“你好B”

这样的输出