Java 扩大番石榴系列
我想扩展LinkedHashMultimap(Guava16.0.1),主要是添加返回常用预填充贴图的方法Java 扩大番石榴系列,java,guava,Java,Guava,我想扩展LinkedHashMultimap(Guava16.0.1),主要是添加返回常用预填充贴图的方法 public class MyMap extends LinkedHashMultimap<String, Object> { } 公共类MyMap扩展LinkedHashMultimap{ } 但是,正如我所了解到的,大多数番石榴收集是最终的,而那些不是最终的,不会公开公共构造函数。做出此设计决策的可能原因是什么?实现我的目标的最佳途径是什么?我能想到的最好方法是在我的类
public class MyMap extends LinkedHashMultimap<String, Object> {
}
公共类MyMap扩展LinkedHashMultimap{
}
但是,正如我所了解到的,大多数番石榴收集是最终的,而那些不是最终的,不会公开公共构造函数。做出此设计决策的可能原因是什么?实现我的目标的最佳途径是什么?我能想到的最好方法是在我的类中包装Multimap方法,但这远远不够理想
编辑:
一些用户指出了不允许继承的正当理由。为了把问题扩大一点,我想指出两件事
ArrayList
或HashMap
这样的类被设计为进行扩展,要么这只是一个API设计缺陷。我怀疑后者;但在API发布后,不可能恢复这种设计选择。也许只有像AbstractList
这样的抽象类才应该被声明为非最终类
可能Guava团队认为,像您现在介绍的这样的用例非常罕见,不值得为继承添加支持(YAGNI)
Josh Bloch——他参与了Java API和Guava的设计——是关于这个主题的一个优秀的演示。正如其他人所指出的,您应该更喜欢委托而不是继承 要实现所需的类,您需要做的是使用
LinkedHashMultimap
作为委托进行扩展。下面是一个这样的例子:
public final class MyMap extends ForwardingSetMultimap<String, Object> {
private final SetMultimap<String, Object> delegate =
LinkedHashMultimap.create();
@Override public SetMultimap<String, Object> delegate() {
return delegate;
}
// add your methods here
}
公共最终类MyMap扩展了ForwardingSetMultimap{
私有最终SetMultimap委托=
LinkedHashMultimap.create();
@重写公共SetMultimap委托(){
返回代表;
}
//在这里添加您的方法
}
旁白:您会问“如果公共API中不推荐继承,为什么Java自己的集合类不是最终类?”
我认为答案基本上是,不使用Java自己的集合类
final
(注意:其中一些类,尤其是较新的类,实际上是final
)。正如@Mick Mememonic所指出的,Josh Bloch(设计原始集合API)参与了Guava集合API的设计:Guava API中的设计决策反映了从原始集合API中吸取的经验教训。装饰图案是你的方式吗?如果我理解正确,无论如何,您要添加的方法都没有理由成为实例方法。为什么您只需要扩展LinkedHashMultimap来提供返回预填充映射的实用方法?组合通常比继承更可取,但在这里,似乎您甚至不需要组合:只需要一个实用程序类。你能提供一个你想添加的方法的例子吗?@JBNizet:我意识到我可以通过实用类来实现这一点,这样看起来更干净。顺便说一句,我不明白为什么组合比继承更受欢迎。两者都有合法的用例,而这个用例不是合法的用例,既不是用于继承,也不是用于组合。关于“偏好组合而非继承”,请阅读@JBNizet:在这种情况下,继承不会有危险,因为我只会使用极不可能改变的超类方法,但是,我现在理解了阻止继承的原因。这很好,但我仍然倾向于不同意让课程成为最终课程是一件好事。应该让库的用户来决定他们的用例是否有理由继承。更多的选择几乎总是一件好事。番石榴团队不必努力支持遗传,事实上他们已经努力禁用了它。“更多的选择几乎总是一件好事。”绝对不是。特别是当这些选项使得射中自己的脚变得容易时。扩展集合类时很容易出错。“优先组合而非继承”和“为继承而设计或防止继承”是这里的两个关键设计原则。Guava将正常的实现(如LinkedHashMultimap
)与专门为继承而设计的实现(转发类)分开。最后给出了令人满意的答案。对不起,我想我应该把番石榴的文档读到最后。在“新收藏类型”一节中没有提到转发装饰器,所以我不知道它们。
public final class MyMap extends ForwardingSetMultimap<String, Object> {
private final SetMultimap<String, Object> delegate =
LinkedHashMultimap.create();
@Override public SetMultimap<String, Object> delegate() {
return delegate;
}
// add your methods here
}