Java介面(Interface)多繼承的一點問題
阿新 • • 發佈:2021-02-06
Java“多繼承”
Java的多繼承只出現在介面中。由於類不能多繼承,避免了C++中出現的diamond problem,即有多個父類,且父類有相同方法時不知道繼承哪個的問題。
Java取消了類的多繼承,用介面多繼承來取代之。但是Java介面多繼承也並不是萬無一失的。接下來的例子就描述了一個介面多繼承的困境。
單繼承介面舉例
interface CanEat {
void eat();
}
interface CanDigest extends CanEat {
void digest();
}
class Person implements CanDigest{
String name;
@Override
public void eat() {
System.out.println(name+" is eating!");
}
@Override
public void digest() {
System.out.println(name+" is Digesting!");
}
}
Person類實現了CanDigest介面,CanDigest介面又繼承了CanEat介面。
(人可以吃東西,可以消化。而可以消化的前提是可以吃)
正常多繼承介面舉例
interface CanEat {
void eat();
}
interface CanDrink {
void drink();
}
interface CanDigest extends CanEat,CanDrink {
void digest();
}
class Person implements CanDigest{
String name;
@Override
public void eat() {
System.out.println(name+" is eating!" );
}
@Override
public void digest() {
System.out.println(name+" is digesting!");
}
@Override
public void drink() {
System.out.println(name+" is drinking!");
}
}
此時,能消化介面繼承了能吃、能喝介面。因此實現了能消化介面的Person類必須Override3個方法。
出現問題的多繼承介面
interface CanEat {
void eat();
}
interface CanEat2 {
boolean eat();
}
interface CanDigest extends CanEat,CanEat2 //報錯 {
void digest();
}
此時CanEat 和 CanEat2 介面內的兩個方法名字、引數都相同,但返回值不同。此時編譯器會給出提示,讓你在CanDigest介面中用default實現eat方法。但實際上,無論你如何實現,此段程式碼一直都會報錯。
實現了返回boolean方法的eat,編譯器提示讓你改成void方法。
改成返回void方法,編譯器又提示你改回返回boolean的方法。
原因分析
方法的的過載要求兩個同名方法引數不同。因此對於兩個僅僅是返回值不同的同名方法來說,就會造成模糊。
總結
Java介面多繼承時,上層接口出現兩個同名同參數但不同返回值的方法時,證明介面設計有問題。