首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >接口继承

接口继承
EN

Stack Overflow用户
提问于 2018-05-21 13:04:24
回答 4查看 89关注 0票数 0

我有两个接口:

代码语言:javascript
复制
public interface EventListener {

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

    public static class Data {

    }
}

和:

代码语言:javascript
复制
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,所以它应该能工作,对吗?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2018-05-21 13:10:46

代码语言:javascript
复制
@Override ServerInfoData modify(ServerInfoData data)

不工作,因为它实际上不覆盖EventListener.modify,因为它不会接受除ServerInfoData (及其子类)以外的任何其他Data子类。

您必须处理所有Data类型,或者使接口本身成为通用的,而不仅仅是一种方法:

代码语言:javascript
复制
public interface EventListener<T extends Data> {
    T modify(T data);
}

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

Stack Overflow用户

发布于 2018-05-21 13:13:07

当覆盖超级方法时,不能缩小泛型类型。

代码语言:javascript
复制
<T extends Data> T modify(T data);

接口中的这个方法接受DataData的任何子类。

但是当你覆盖它的时候:

代码语言:javascript
复制
@Override 
ServerInfoData modify(ServerInfoData data);

然后,您的方法不能使用扩展了ServerInfoData类的Data类,因此它破坏了重写的契约。

票数 1
EN

Stack Overflow用户

发布于 2018-05-21 13:17:01

我不能充分解释它不能工作的具体技术原因,但我可以解释修复。

您的接口应该在类级别使用泛型,而不是方法级别。我们还需要将Data移出EventListener (由于creation deadlock):

代码语言:javascript
复制
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;
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50449571

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档