【问题标题】:Implementing Incompatible Interfaces [duplicate]实现不兼容的接口
【发布时间】:2013-06-18 16:19:15
【问题描述】:

我正在尝试构建一个实现QueueMap 的类。两个接口都定义了remove(Object) 方法,但返回类型不同:

public interface Collection<E> { //Queue extends Collection, which has the problem method

    public boolean remove(Object e);

    //...
}

public interface Map<K,V> {

    public V remove(K key);

    //...
}

public class QueuedMap<K,V> extends AbstractMap implements Queue {

    public V remove(K key) {/* ... */}
    //ERROR: V is not compatible with boolean

    //...
}

K 的类型擦除导致这两个方法签名发生冲突。我不能拥有其中一个,因为它是无效的覆盖,我不能同时拥有两者,因为它们具有相同的签名。有什么办法可以让这两个接口共存?

【问题讨论】:

  • 即兴发挥,对我来说似乎不可能。
  • 如果您调用 remove(key),您的班级将如何决定使用哪一个?

标签: java inheritance interface type-erasure


【解决方案1】:

我认为在这种特殊情况下这是不可能的。如果两个类都返回 Object 类型,您会有一些机会,但是由于您混合了基本类型和对象类型,因此没有兼容的类型可以同时支持这两个接口。

另一种方法可能是实现适当的兼容接口,然后使用组合来存储内部结构并根据需要将函数调用映射到该结构。这将假定您不需要同时满足或可用作这两个接口,而是需要一个特别是您需要公开的接口。

但是,如果你需要让这个类作为两个不兼容的接口可替换,那就做不到了。

【讨论】:

    【解决方案2】:

    您可以使用 Queue 具有的所有方法减去 remove 方法来创建自己的接口 MyQueue 并使用它。您可以为MyQueue 接口提供一个Queue toQueue() 方法,该方法返回转换为队列的对象。

    这个转换过程可能只涉及返回一个匿名 Queue 的新实例,对于每个方法 X,它只需调用/返回 this.[X]。对于 remove 方法,您将调用 this.remove() 但随后返回布尔值而不是 this.remove() 调用的返回值。

    【讨论】:

    • 这不太可能有用。实现java.util.Queue 的目的是使此类的实例可以传递到需要java.lang.Queue 的方法中。实施MyQueue 不会实现这一点。
    • @AndrzejDoyle 我同意,但如果这个解决方案适用于 OP 的用例或引发进一步讨论,我想我会发布它
    猜你喜欢
    • 2013-10-08
    • 2013-06-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-16
    相关资源
    最近更新 更多