在 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? *
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