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

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

上一篇:SQL Server 利用批量(batchsize)提交加快数据生成/导入


下一篇:javaweb学习总结(十八)——JSP属性范围(转)