簡體   English   中英

在Java中的子類中實現抽象方法

[英]Implementing abstract methods in a subclass in Java

我已經使我的代碼盡可能通用,以便在將來嘗試幫助人們。 我的抽象類有一個類類的方法和類型類的輸入。 在擴展抽象的類中,我嘗試實現該方法無濟於事。 我究竟做錯了什么?

public abstract class A {
    public abstract A method1(A arg);
}

public class B extends A {
    @Override
    public B method1(B arg) { "...insert code here"} // Error: The method method1(B) must override or implement a supertype method
}

要實現您想要的:將參數的類型與聲明的類相關聯,您可以使用泛型。

抽象類:

public abstract class A <T extends A<T>> {
    public abstract T method1(T arg);
}

具體課程:

public class B extends A<B> {
    @Override
    public B method1(B arg) { 
     ...
      return ...
    }
}

應保留參數的類型和否。 返回類型(如果它是基本類型)應保持相同,但如果它是引用類型,則它可以是子類類型。

在您的情況下,將此public B method1(B arg) { "...insert code here"}更改為public B method1(A arg) { "...insert code here"}

想想Liskov替換原則 :為了與超類無法區分,子類必須接受超類所具有的所有相同參數; 並返回超類可能的東西。

另一種方法是子類方法可以:

  • 返回超類方法的更具體的類型(因為這是超類可能返回的值); 例如,如果超類返回Object ,則子類可以返回String ,因為所有String都是Object

    這稱為協變返回類型 ,在Java中是允許的。 子類不僅可以返回更具體的返回類型,還可以拋出比超類更具體的已檢查異常; 但他們也不能聲明它們拋出超類方法拋出的已檢查異常。

  • 接受比超類方法更通用的類型(因為這允許子類接受超類所有的參數)。

    這將被稱為逆變參數類型 ; 但它不是在Java的許可。 原因是在Java中選擇重載的方式:遺憾的是,方法簽名(包括參數類型,但不包括返回類型)必須相同

語言規范的相關部分是JLS Sec 8.4.8.3

您的問題是使參數類型為B :這比A 具體,因此B的實例不能替代A的實例,因為A.method1接受參數A ,而B.method1不接受。

使B.method1取一個A類參數。

A.method1的契約意味着作為A每個對象必須具有可以接受任何A對象的method1

B.method1的情況下,它可以采用B對象,但它不能采用另一個A

你寫的每一件事都是正確的,除了重疊的方法參數類型,你不能在重寫子類時改變超類抽象方法的簽名。

public abstract class A {
    public abstract A method1(A arg);
}

public class B extends A {
    @Override
    public B method1(A arg) { "...insert code here"} // Error: The method method1(B) must override or implement a supertype method
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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