[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