抽象类的抽象方法跟接口的方法相同

抽象类

public abstract class APerson {

	public abstract void speak();
}

接口

public interface IPerson {

	void speak();
}

子类

public class ZhangSan extends APerson implements IPerson {

	@Override
	public void speak() {
		System.out.println("haha");
	}

	public static void main(String[] args) {
		ZhangSan zhangSan = new ZhangSan();
		zhangSan.speak();
	}
}

控制台打印出来的是:haha

结论

子类中的 speak 方法,实现的是父类的抽象方法,默认覆盖接口中的同名方法。

抽象类的具体方法跟接口的方法相同

修改抽象类的抽象方法为具体方法

public abstract class APerson {

	public void speak(){
		System.out.println("hahaha");
	}
}

子类覆盖的方法去掉

public class ZhangSan extends APerson implements IPerson {

	public static void main(String[] args) {
		ZhangSan zhangSan = new ZhangSan();
		zhangSan.speak();
	}
}

控制台打印的是:hahaha

结论

子类隐式继承了抽象类的 speak 方法,默认覆盖了接口中的同名方法。

证明结论

如何证明接口中的方法被抽象类的方法覆盖了呢?

1.把抽象类中的具体方法的访问修饰符改为 protected

image

可以看到报错了:继承的方法aperson.speak()无法隐藏iperson中的公共抽象方法

因为抽象类的具体方法的访问修饰符改为 protected 后,子类隐式继承抽象父类的 speak() 方法的访问修饰符也是 protected,与接口中的 public 不符。java 中规定,子类覆盖父类的方法,方法的访问权限不能比父类小

2.把抽象类中的抽象方法的访问修饰符改为 protected

protected abstract void speak();

image

可以看到当子类的方法访问修饰符为 protected 时也报错了:无法降低从IPerson继承的方法的可见性

因为子类实现抽象父类的方法时,方法的访问修饰符为 protected,比接口的方法 public 的访问范围小,所以不能将抽象父类的方法覆盖接口中同名的方法。

所以可以说明当一个类继承的抽象类和实现的接口有相同的方法签名时,会默认将抽象父类的方法覆盖接口的方法。

原文链接:https://miansen.wang/2019/06/17/1/