一个类从其超类继承所有非私有静态方法。在子类中重新定义继承的静态方法称为方法隐藏。子类中的重定义静态方法隐藏其超类的静态方法。在类中重定义非静态方法称为方法覆盖。
关于方法隐藏的重定义方法(名称,访问级别,返回类型和异常)的所有规则与方法覆盖相同。
class MySuper { public static void print() { System.out.println("Inside MySuper.print()"); } } class MySubclass extends MySuper { public static void print() { System.out.println("Inside MySubclass.print()"); } } public class Main { public static void main(String[] args) { MySuper mhSuper = new MySubclass(); MySubclass mhSub = new MySubclass(); MySuper.print(); MySubclass.print(); ((MySuper) mhSub).print(); mhSuper = mhSub; mhSuper.print(); ((MySubclass) mhSuper).print(); } }
上面的代码生成以下结果。
Inside MySuper.print() Inside MySubclass.print() Inside MySuper.print() Inside MySuper.print() Inside MySubclass.print()
子类中的字段声明(静态或非静态),在其父类中会隐藏具有相同名称的继承字段,也就是说在字段名称相同,子类读取字段时,只能读取子类中的字段无法读取到父类中的字段。
在字段隐藏的情况下,不考虑字段的类型及其访问级别。字段隐藏仅基于字段名称。
class MySuper { protected int num = 100; protected String name = "Tom"; } class MySub extends MySuper { public void print() { System.out.println("num: " + num); System.out.println("name: " + name); } } class MySub2 extends MySuper { // Hides num field in MySuper class private int num = 200; // Hides name field in MySuper class private String name = "Jack"; public void print() { System.out.println("num: " + num); System.out.println("name: " + name); } } public class Main { public static void main(String[] args) { MySub fhSub = new MySub(); fhSub.print(); MySub2 fhSub2 = new MySub2(); fhSub2.print(); } }
执行上面的代码,将会得到如下结果 -
num: 100 name: Tom num: 200 name: Jack
以下代码显示了如何使用 super
关键字访问超类中的隐藏字段。
class MySuper { protected int num = 100; protected String name = "Tom"; } class MySub extends MySuper { // Hides the num field in MySuper class private int num = 200; // Hides the name field in MySuper class private String name = "Jack"; public void print() { System.out.println("num: " + num); System.out.println("super.num: " + super.num); System.out.println("name: " + name); System.out.println("super.name: " + super.name); } } public class Main { public static void main(String[] args) { MySub s = new MySub(); s.print(); } }
上面的代码生成以下结果。
num: 200 super.num: 100 name: Jack super.name: Tom
字段隐藏发生在一个类声明一个变量与来自其继承超类中的变量的名称相同时。字段隐藏仅基于字段的名称。子类可使用关键字super
来访问超类的隐藏字段。子类可以使用简单的名称来访问其主体中的重定义的字段。