【问题标题】:Can't include the same interface with different parameters?不能包含具有不同参数的相同接口吗?
【发布时间】:2010-12-12 07:00:28
【问题描述】:

考虑以下示例:

public class Sandbox {
    public interface Listener<T extends JComponent> {
        public void onEvent(T event);
    }

    public interface AnotherInterface extends Listener<JPanel>, Listener<JLabel> {
    }
}

这会失败并出现以下错误

/media/PQ-WDFILES/programming/Sandbox/src/Sandbox.java:20: Sandbox.Listener cannot be inherited with different arguments: <javax.swing.JPanel> and <javax.swing.JLabel>
        public interface AnotherInterface extends Listener<JPanel>, Listener<JLabel> {
               ^
1 error

为什么?生成的方法没有重叠。事实上,这基本上意味着

public interface AnotherInterface {
    public void onEvent(JPanel event);
    public void onEvent(JLabel event);
}

那里没有重叠。那么为什么会失败呢?


如果您想知道我在做什么并有更好的解决方案:我有一堆事件和一个监听器接口,几乎与上面的 Listener 类完全相同。我想创建一个适配器和一个适配器接口,为此我需要使用特定事件扩展所有侦听器接口。这可能吗?有没有更好的方法来做到这一点?

【问题讨论】:

    标签: java generics


    【解决方案1】:

    没有。你不能。 这是因为泛型仅在编译器级别受支持。所以你不能做这样的想法

    public interface AnotherInterface {
        public void onEvent(List<JPanel> event);
        public void onEvent(List<JLabel> event);
    }
    

    或实现带有多个参数的接口。

    更新

    我认为解决方法是这样的:

    public class Sandbox {
    //    ....
        public final class JPanelEventHandler implements Listener<JPanel> {
            AnotherInterface target;
            JPanelEventHandler(AnotherInterface target){this.target = target;}
            public final void onEvent(JPanel event){
                 target.onEvent(event);
            }
        }
    ///same with JLabel
    }
    

    【讨论】:

    • 啊,我忘记了类型擦除。你知道另一种方法来完成我想做的事情吗?
    • @Stas 这似乎是每个事件的大量代码(〜50)。也许我应该回到显式地为每个事件创建一个侦听器?
    • @TheLQ,取决于您的应用程序。通常,它可以是匿名类。
    • @Stas 我在思考如何将您的课程整合到我的设计中时遇到了麻烦。而且我还发现拥有 2 个扩展 Listener 然后实现它们的子接口是行不通的。我在这里没有想法
    • @TheLQ,有错字 - JPanelEventHendler -> JPanelEventHandler 在构造函数中。
    【解决方案2】:

    不要忘记在 java 中泛型是使用类型错误来实现的,但在编译后扩展仍然存在。

    所以你要求编译器做什么(在类型擦除之后),

    public interface AnotherInterface extends Listener, Listener;
    

    你根本不能做泛型。

    【讨论】:

    • 我忘记了类型擦除。你知道另一种方法来完成我想要完成的事情吗?
    • class One implements Two, Three { } interface Other&lt;T&gt; { } interface Two extends Other&lt;Object&gt; { } interface Three extends Other&lt;Object&gt; { } - 将一个 Object 更改为其他任何内容,您就会收到错误消息。所以,这并不是因为它重复扩展了接口,它确实与泛型有关。
    猜你喜欢
    • 2017-12-25
    • 2013-08-27
    • 2013-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-28
    • 2020-03-30
    相关资源
    最近更新 更多