[英]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.