Java覆盖两个接口,方法名称冲突。

7
我正在一个类中实现Map<V,K>Collection<V>接口,但是remove(Object)方法出现在两个接口中,因此eclipse会显示一些错误。虽然返回类型不同(一个返回boolean,另一个返回V),但似乎并不重要。
有没有办法告诉Java / Eclipse哪个方法被实际覆盖?
编辑:我有一个所有值都必须实现的接口,它提供了一个getKey()方法,使得可以为映射编写一个add函数。但似乎没有办法让这一个类同时看起来像一个地图和一个集合?

你可能想要表达你打算做什么。Map 基本上是一个键值字典。Collection 只是一堆东西。它们在概念上根本不是同一件事。你的意思是想要一个 Map,其 keys 可以作为 Collection 访问吗?例如,keySet() 就可以实现这个功能。 - Sean Owen
5个回答

8

不好意思,没有直接的方法。

实际上,动态绑定考虑到签名,但不包括返回类型,因此Java编译器不能接受同一类别有相同签名但返回类型不同的两种方法。如果两个方法具有相同的名称和相同的参数,则它们必须具有相同的返回类型,对您来说很不幸。

唯一的方法是将行为分成两个不同的类并将它们组合在一起。也许像Collection<V> asCollection()这样的方法或类似方法会有所帮助。


这是有关方法签名的JLS文档:http://java.sun.com/docs/books/jls/third_edition/html/classes.html#8.4.2 - rit

1

不,没有解决这种冲突的方法。

您应该考虑使用组合委托,而不是继承至少其中一个接口,或者将类的功能分为两个类,这真的取决于您具体的问题。


如果我让我的Map类继承Collection类并将Collection类中的remove方法设置为final,那么在Map类中仍然会出现错误。或者我应该如何使用组合? - Franz Kafka
如果你让你的“Map类扩展Collection”,那么你正在使用继承。如果你想要做的本质上是一个带有一些自定义差异的Map,那么只需将其扩展为Map即可。如果你需要在内部使用Collection来实现某些功能,可以将该Collection声明为私有变量,并通过委托公开一些必要的方法(如果需要)。你可以定义一个方法,只需将调用传递给私有变量上的类似方法即可。 - stivlo
谢谢,我明白了。但是当我使用委托时,我的类失去了真正集合的外观。应用程序使用这个实现应该很简单,而不必担心调用一些toCollection()方法。但这似乎是不可能的。 - Franz Kafka

1

Map已经有了keySet(),它是键的集合。为什么还需要Collection呢?如果是这样的话,只需编写两个方法,如asMapasCollection,它们返回不同类型即可。


我正在为地图编写自定义add()方法。 - Franz Kafka
而且?.. 你总是可以使用 yourObject.asMap().add(..custom..) - kan

0
你可能需要使用组合而不是继承。不幸的是,Java没有语言级别的支持 - 我的意思是可以做到,但这是不必要的费力的。

0

你需要重新思考你的设计。从根本上讲,地图与集合是不同的。想一想Collection.add()方法。在地图中添加没有键或没有值的键是否有意义?

我认为(取决于你的应用程序),最好的选择是实现一个地图,但当你需要一个集合时,使用它的方法来获取键、值或键值对的集合。


看看我的编辑,有一个接口提供从值获取键的方法。我知道我想做什么,唯一的问题是如何实现 :-) - Franz Kafka
“add”只是一个例子。我的评论仍然适用。 - JeremyP

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接