[Java] 继承中,父类被覆盖的成员变量、方法的可访问性

在 Java 的继承机制里,在子类内部,可以访问父类被覆盖的变量和方法;在子类外部,可以访问父类的被覆盖变量,但是不能访问父类的被覆盖方法。

父类中被覆盖的方法不能在外部被方法,这是出于封装的考虑。

例子:

Super, 父类,拥有一个成员变量 x ,和成员方法 doSomething()。

Point,继承 Super, 但覆盖了 Super 的 x 和 doSomething(),拥有自己的同名成员成员 x 和 doSomething()。

StaticDemo1, 演示在继承中,在内部,可以调用某个类的父类被覆盖的变量,在外部同样也可以。

StaticDemo2, 演示在继承中,在内部,可以调用某个类的父类被覆盖的方法,但是在外部不可以这么做。

具体代码:

Super, 父类

public class Super {
    String x = " Super ";

    public void doSomething(){
        System.out.println(" dosomething in Super ");    
    }
}

Point, 子类,继承 Super 

public class Point extends Super{
    String x = " Point ";
    
    public void printBoth(){
        System.out.println(x);
        System.out.println(super.x);
    }
    
    public void doSomething(){
        System.out.println(" dosomething in Point ");    
    }
    
    public void doBoth(){
        doSomething();
        super.doSomething();
    }
}

StaticDemo1,演示访问父类被覆盖的成员变量

public class StaticDemo1 {
    public static void main(){
        Point sp = new Point();
        sp.printBoth();
                
        System.out.println(sp.x);
        System.out.println(((Super)sp).x);    
    }
}

输出如下,可见无论在子类内部,还是其他第三方的类中,都可以访问到父类被覆盖的成员变量

 Point 
 Super 
 Point 
 Super 

 

StaticDemo2,演示调用父类被覆盖的方法

public class StaticDemo {
    public static void main(){
        Point sp = new Point();    
        sp.doBoth();
sp.doSomething(); ((Super)sp).doSomething(); } }

输出如下,可见在子类内部可以调用父类的被覆盖的方法,但是在外部无法调用父类的被覆盖方法。

这是出于封装的考虑,避免外部程序直接调用父类的被覆盖方法,而躲过了子类对被覆盖方法新增的验证逻辑。同样出于封装的考虑,在子类可以调用父类的被覆盖方法,如 super.x 可行, 但是无法调用祖先的被覆盖方法,如 super.super.x 不可行

 dosomething in Point 
 dosomething in Super 
 dosomething in Point 
 dosomething in Point

参考资料:

Can java call parent overridden method in other objects but not subtype? stackOverflow

8.3.1.1 static Fields, The Java Language Specification, Java SE 8 Edition

8.4.3.2 static Methods, The Java Language Specification, Java SE 8 Edition

原文地址:https://www.cnblogs.com/TonyYPZhang/p/5597315.html