类
类与类之间存在继承关系的时候,要是子类和父类定义了一个相同签名的静态方法时,两个版本的方法被谁调用取决于实际调用它的类,即子类对父类方法隐藏了。另外,如果子类和父类定义了一个相同签名的实例方法时,用过父类引用指向子类实例的方式调用该方法的时候,实际调用的是子类方法,即父类方法被重写。
//父类
public class Animal {
public static void testStaticMethod() {
System.out.println("this static method is belong to superclass");
}
public void testInstanceMethod() {
System.out.println("this instance method is belong to superclass");
}
}
//子类
public class Cat extends Animal{
public static void testStaticMethod() {
System.out.println("this static method is belong to subclass");
}
public void testInstanceMethod() {
System.out.println("this instance method is belong to subclass");
}
}
//测试类
public class MyTestOverridingAndHidingMethod {
@Test
public void test() {
Animal obj = new Cat();
Animal.testStaticMethod();
obj.testInstanceMethod();
Cat.testStaticMethod();
//The Cat class overrides the instance method in Animal and hides the static method in Animal.
}
//静态方法和实例方法在被子类重写的时候,会出现不同的结果。对静态方法隐藏,对实例方法覆盖。
}
- 实例方法:不带static的方法
- 静态方法:带static的方法
注意:如果子类将父类相同签名的实例方法修改为静态方法,编译报错,反之亦然。
另外一个点需要提及下:在一个类里面,和父类有相同名字的属性会隐藏父类的属性,即时他们的类型不同。在子类里,这个父类的属性不会被子类通过简单的属性名所引用。可以通过super.field对其引用。
接口
JDK1.8之后,接口支持了默认方法。在接口的继承中,方法会是怎么样的继承规则呢?编译器只认两条准则:
- 实例方法优于默认方法
- 在实现类的父类有相同的祖先时,被重写过的方法会被实现类忽略
public interface Flyable {
default public String identifyMyself() {
return "im am able to fly";
}
}
public interface Mythical {
default public String identifyMyself() {
return "im am mythical creature";
}
}
public class Horse {
public String identifyMyself() {
return "im am a horse";
}
}
public class Pegasus extends Horse implements Flyable,Mythical{
//在父类接口的默认方法和父类都实现了相同签名的方法时,优先调用实例方法。编译器会认为实例方法会比默认方法好。
public static void main(String... args) {
Pegasus pegasus = new Pegasus();
System.out.println(pegasus.identifyMyself());
}
}
public interface Animal {
default public String identifyMyself() {
return "i am an animal";
}
}
public interface EggLayer extends Animal{
default public String identifyMyself() {
return "i am able to lay eggs";
}
}
public interface FireBreather extends Animal {
}
public class Dragon implements EggLayer, FireBreather {
//当一个类的父类都有同一个祖先,且父类已经重写了祖先的方法,那么该类在调用这个方法的时候,被覆盖的方法会被忽略掉。
public static void main(String...args) {
Dragon dragon = new Dragon();
System.out.println(dragon.identifyMyself());
}
}
注意:接口里不存在静态方法继承一说
当然,最常规的实现类实现接口的抽象方法也是属于继承里面的。
public interface Mammal {
String identifyMyself();
}
public class Horse {
public String identifyMyself() {
return "I am a horse.";
}
}
public class Mustang extends Horse implements Mammal {
public static void main(String... args) {
Mustang myApp = new Mustang();
System.out.println(myApp.identifyMyself());
}
}