java子类继承方法和接口方法重名/冲突(上)
在上一篇文章Java抽象类和接口的区别中,为了说明抽象类和接口的区别,我举了四个代码段例子:
abstract class Fish{//鱼抽象类 private boolean isFast; abstract void desrcibe(); protected void swim() { System.out.println("我能游泳"); } } class Tuna extends Fish{//金枪鱼实现抽象类 boolean isFast = true; @Override //重写 void desrcibe() { System.out.println("这是一条金枪鱼"); } } interface aquatic{//水生接口 boolean isAquatic = true; void swim(); void breath(); } class Carp implements aquatic{//鲤鱼实现水生接口 @Override public void breath() { System.out.println("我用鳃呼吸"); } @Override public void swim() { System.out.println("我游得很慢"); } }
注意上述代码中抽象类Fish和接口aquatic中有一个同名、同签名(参数列表相同)方法swim,而Fish实现了swim方法
在这个例子中,鲤鱼也是鱼类的一种,可以同时继承Fish类和实现aquatic接口,于是代码可以这样写:
class Carp extends Fish implements aquatic{ @Override public void breath() { System.out.println("我用鳃呼吸"); } @Override void desrcibe() { System.out.println("这是一条鲤鱼"); } }
既然Fish类提供了swim的默认实现,那么,Fish类的默认swim方法能不能把aquatic接口的swim方法覆盖呢?
IDE给出了警告"The inherited method Fish.swim() cannot hide the public abstract method in aquatic"
难道意思是继承来的方法就没办法实现接口的方法了吗?
事实上原因是:访问权限不能满足。
Java、C++都规定了子类的访问权限不能比父类小,也就是说,若抽象方法/接口中方法的声明是public,子类继承来的方法也只能是public修饰(因为接口的方法必是public,所以子类实现接口的方法也必须是public)。在我们给出的第一段代码中,
抽象Fish类提供的swim的默认实现是protected:
abstract class Fish{ private boolean isFast; abstract void desrcibe(); protected void swim() {//注意该处权限 System.out.println("我能游泳"); } }
那么Carp子类继承来的swim方法也默认是protected权限的。
而第三段代码中,接口aquatic的swim要求是public的(接口方法只能是public):
interface aquatic{ boolean isAquatic = true; void swim(); void breath(); }
那么Carp从Fish继承来的swim方法的protected权限是满足不了接口方法的要求的。
该程序段可以通过以下改动任一使之成立:
- 将Fish抽象类提供的默认swim方法改为public修饰
- 这样写代码也能使子类的swim权限满足public:
class Carp extends Fish implements aquatic{ @Override public void breath() { System.out.println("我用鳃呼吸"); } public void swim(){//调用父类的swim方法,而将权限改为public super.swim(); } @Override void desrcibe() { System.out.println("这是一条鲤鱼"); } }
5+

软件工程大三在读学生,用个人网站记录学习动态
说点什么