![](/img/trans.png)
[英]How to make two classes which both have method with the same name, signature and return type behave like they would implement the same interface
[英]Two interface have same method name with different return type
這個問題是為了理解Java中的接口。 這是在Java中實現接口的一個非常簡單的示例。
interface ParentA {
void display();
}
interface ParentB {
int display();
}
class Child implements ParentA, ParentB {
@Override
public void display() {
System.err.println("Child ParentA");
}
//ERROR : The return type is incompatible with ParentB.display()
//So added method with int return type too
@Override
public int display() {
System.err.println("Child ParentB");
}
}
這種情況可能發生在大型Java應用程序中,其中兩個接口可以具有相同名稱的方法。 我認為,由於返回類型不同,JVM將知道我們覆蓋哪個接口的方法。
對此最好的解釋是什么? 這種情況有意義嗎?
提前致謝
因為不允許使用具有相同簽名的方法,所以它會混淆編譯器以從聲明的一次檢測精確的覆蓋等效方法。
JLS(§8.4.2)
兩個方法或構造函數M和N如果有,則具有相同的簽名,
- 同名
- 相同的類型參數(如果有的話)( §8.4.4 ),和
- 在將N的形式參數類型調整為M的類型參數之后,使用相同的形式參數類型。
在類中聲明具有覆蓋等效簽名的兩個方法是編譯時錯誤。
如果您發現自己處於這種情況並且無法以更清晰的方式解決,則可以使用一個或兩個內部類來轉發對新命名方法的調用:
class Child {
private class ParentAImp implements ParentA {
@Override
public void display() {
displayParentA();
}
}
private class ParentBImp implements ParentB {
@Override
public int display() {
return displayParentB();
}
}
public ParentA asParentA(){ return new ParentAImp(); }
public ParentB asParentB(){ return new ParentBImp(); }
private void displayParentA() {
System.err.println("Child ParentA");
}
private int displayParentB() {
System.err.println("Child ParentB");
return 0;
}
}
現在回顧從Child
到接口你需要做的事情:
ParentA parentA = child.asParentA();
ParentB parentB = child.asParentB();
在同一個類中不可能有兩個具有相同簽名和不同返回類型的方法。
簽字的定義:
方法名稱和參數列表的組合。
發生這種情況是因為jvm兩者不可能在僅與返回類型不同的方法之間進行選擇。 jvm infact只能調查方法的名稱和調用的參數類型。
所以你的例子在java中是不可能的。
可能你必須創建兩個類,一個用於接口。
要實現覆蓋,您將打破重載規則。
因此,在您的情況下,您不能使用相同的方法名稱具有相同的方法參數(在您的情況下沒有參數)和不同的返回類型。
如果您向其中一個接口方法添加參數,那么您的代碼將被編譯。
interface ParentA {
void display();
}
interface ParentB {
int display(int x);
}
class Child implements ParentA, ParentB {
@Override
public void display() {
System.err.println("Child ParentA");
}
@Override
public int display(int x) {
System.err.println("Child ParentB");
return 0;
}
}
如果你從一個代碼調用Child的一個實例上的方法來考慮它:
Child child = new Child();
child.display();
將調用哪種顯示方法? 看到它可能是任何一種方法,您會看到編譯時錯誤。
在Java 8中使用一種有趣的方法是在其中一個接口中使用默認方法; 這些都有自己的一套規則。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.