簡體   English   中英

接口中的繼承

[英]Inheritance in interface

我有兩個界面:

public interface EventListener {

    <T extends Data> T modify(T data);

    public static class Data {

    }
}

和:

public interface ServerInfoEventListener extends EventListener {

    // This works
    @Override ServerInfoData modify(Data data);

    // This doesn't work!
    @Override ServerInfoData modify(ServerInfoData data);

    public static class ServerInfoData extends Data {
        public ServerInfoData(String motd, int playerCount, int maxPlayers) {
            this.motd = motd;
            this.playerCount = playerCount;
            this.maxPlayers = maxPlayers;
        }
        public String motd;
        public int playerCount;
        public int maxPlayers;
    }
}

從注釋中可以看到, modify(ServerInfoData data)無法編譯。 為什么不呢,我該如何解決呢? ServerInfoData擴展了Data ,所以它應該起作用,對吧?

@Override ServerInfoData modify(ServerInfoData data)

不起作用,因為它實際上不會覆蓋EventListener.modify因為它將不接受ServerInfoData及其子類)以外的Data任何其他子類。

您要么必須處理所有 Data類型,要么使接口本身通用,而不僅僅是一種方法:

public interface EventListener<T extends Data> {
    T modify(T data);
}

public interface ServerInfoEventListener extends EventListener<ServerInfoData> {
    @Override ServerInfoData modify(ServerInfoData data);
}

覆蓋super方法時,不能縮小通用類型的范圍。

<T extends Data> T modify(T data);

此從接口方法接受Data和的任何亞類Data

但是,當您覆蓋它像:

@Override 
ServerInfoData modify(ServerInfoData data);

然后,您的方法無法兄弟類ServerInfoData類,后者擴展了Data類,因此它破壞了覆蓋的協定。

我無法充分解釋其無法正常工作的具體技術原因,但可以解釋此修復程序。

您的接口應在類級別而不是方法級別使用泛型。 我們還需要將DataEventListener移出(由於創建死鎖 ):

class Data
{
    //...
}

interface EventListener<T extends Data>
{
    T modify(T data);
}

interface ServerInfoEventListener extends EventListener<ServerInfoEventListener.ServerInfoData>
{
    @Override ServerInfoData modify(ServerInfoData data);

    class ServerInfoData extends Data {
        //...
    }
}

class ServerInfoEventListenerImpl implements ServerInfoEventListener
{
    @Override
    public ServerInfoData modify(final ServerInfoData data)
    {
        return null;
    }
}

如該接口中聲明EventListener方法modify需要類型的參數Data (或任何亞類)

ServerInfoData modify(ServerInfoData data); 接受類型為ServerInfoData參數,但是接口中的定義說“應該接受任何東西,碰巧具有Data類型的超類”,這意味着子類中方法的參數類型與接口中聲明的類型不匹配。

考慮以下示例:

public static class AnotherData extends Data {
    // Whatever
}

public void main() {
    EventListener el = new ServerInfoEventListener() {...};
    el.modify(new AnotherData()); // We have a problem
}

問題:沒有方法實現可以處理AnotherData ,但是應該可以實現,因為EventListener這樣說。 ServerInfoData modify(ServerInfoData data)無法接受,因為AnotherData不是ServerInfoData實例

希望這可以幫助。

暫無
暫無

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

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