简体   繁体   English

接口中的继承

[英]Inheritance in interface

I have two interfaces: 我有两个界面:

public interface EventListener {

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

    public static class Data {

    }
}

And: 和:

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;
    }
}

As you can see from the comments, modify(ServerInfoData data) does not compile. 从注释中可以看到, modify(ServerInfoData data)无法编译。 Why not, and how do I fix it? 为什么不呢,我该如何解决呢? ServerInfoData extends Data , so it should work, right? ServerInfoData扩展了Data ,所以它应该起作用,对吧?

@Override ServerInfoData modify(ServerInfoData data)

does not work because it does not actually override the EventListener.modify since it will not accept any other subclass of Data other than ServerInfoData (and its subclasses). 不起作用,因为它实际上不会覆盖EventListener.modify因为它将不接受ServerInfoData及其子类)以外的Data任何其他子类。

You either have to handle all Data types or make the interface itself generic, not only one method: 您要么必须处理所有 Data类型,要么使接口本身通用,而不仅仅是一种方法:

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

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

You cannot narrowing down the generic type when override super method. 覆盖super方法时,不能缩小通用类型的范围。

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

This method from interface accepts Data and any subclass of Data . 此从接口方法接受Data和的任何亚类Data

But when you override it like: 但是,当您覆盖它像:

@Override 
ServerInfoData modify(ServerInfoData data);

Then your method cannot sibling class of ServerInfoData which extends Data class, hence it breaks the overridden contract. 然后,您的方法无法兄弟类ServerInfoData类,后者扩展了Data类,因此它破坏了覆盖的协定。

I can't adequately explain the specific technical reason why it won't work, but I can explain the fix. 我无法充分解释其无法正常工作的具体技术原因,但可以解释此修复程序。

Your interface should use generics at the class-level, not the method-level. 您的接口应在类级别而不是方法级别使用泛型。 We're also required to move Data out of EventListener (due to creation deadlock ) : 我们还需要将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;
    }
}

As declared in the interface EventListener method modify requires argument of type Data (or any subclass) 如该接口中声明EventListener方法modify需要类型的参数Data (或任何亚类)

ServerInfoData modify(ServerInfoData data); takes argument of type ServerInfoData , however definiton in interface says "It should take anything, that happens to have superclass of type Data " which means that type of arguments of method in subclass does not match what is declared in interface. 接受类型为ServerInfoData参数,但是接口中的定义说“应该接受任何东西,碰巧具有Data类型的超类”,这意味着子类中方法的参数类型与接口中声明的类型不匹配。

Consider this example: 考虑以下示例:

public static class AnotherData extends Data {
    // Whatever
}

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

The problem: There is no method implementation to handle AnotherData , but there is supposed to be, because EventListener says so. 问题:没有方法实现可以处理AnotherData ,但是应该可以实现,因为EventListener这样说。 ServerInfoData modify(ServerInfoData data) Can't take it, because AnotherData is not instanceof ServerInfoData ServerInfoData modify(ServerInfoData data)无法接受,因为AnotherData不是ServerInfoData实例

Hope this helps. 希望这可以帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM