簡體   English   中英

為什么我不能使用class的實現作為參數覆蓋方法

[英]Why I can not override method using implementation of class as parameter

我有簡單的抽象結構

public abstract class Data<A extends Serializable> {

}

然后是這個類的String實現

public class StringData extends Data<String> {

}

然后我有接口:

public interface Testicek<A extends Serializable> {

    public abstract Data<A> test(Data<A> bla);

}

現在我想創建實現此接口的類:

public class TesticekImpl implements Testicek<String> {


    // OK
    @Override
    public StringData test(Data<String> bla) {
        return null;
    }

    // compilation error
    //@Override
    //public StringData test(StringData bla) {
    //    return null;
    //}

}

為什么我不能將我的StringData類用作參數,它只能在返回類型中使用? 返回類型和參數的簽名是相同的。

public interface Testicek<A extends Serializable> {

    public abstract Data<A> test(Data<A> bla);

}

Java允許協變返回類型 ,這意味着接口的實現可以返回比父接口更多的特定類型,因為那些更具體的類型仍然是特定於較少類型的實例,因此它們符合接口的約定。

但是,您不能使用更具體的參數類型,因為接口的契約表明它必須接受該類型的任何實例。

Liskov替換原則告訴我們,子類必須接受不再具有限制性的參數,並且必須返回不再一般的值。

Java不允許您使用“限制較少”的參數類型,因為它解析了在編譯時調用的方法 (這已經非常復雜了)。 從理論的觀點來看,這是不必要的限制,但從實際的觀點來看更簡單。

在接受和返回相同類型方面:在接口中聲明另一個類型變量:

public interface Testicek<A extends Serializable, D extends Data<A>> {

    public abstract D test(D bla);

}

然后你的實現可以是:

public class TesticekImpl implements Testicek<String, StringData> {
    @Override
    public StringData test(StringData bla) {
        return null;
    }
}

暫無
暫無

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

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