簡體   English   中英

兩個接口具有相同的方法名稱和不同的返回類型

[英]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中是不可能的。

可能你必須創建兩個類,一個用於接口。

要實現覆蓋,您將打破重載規則。

方法重載的條件

  1. 方法的參數數量不同。
  2. 參數類型不同(例如將float的參數更改為int)。

因此,在您的情況下,您不能使用相同的方法名稱具有相同的方法參數(在您的情況下沒有參數)和不同的返回類型。


如果您向其中一個接口方法添加參數,那么您的代碼將被編譯。

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM