繁体   English   中英

扩展番石榴收藏品

[英]Extending Guava collections

我想扩展LinkedHashMultimap(Guava 16.0.1),主要是添加返回常用预填充地图的方法。

public class MyMap extends LinkedHashMultimap<String, Object> {
}

但是,正如我所知,大多数番石榴收藏品是最终的,而那些不是,不会暴露公共建设者。 这个设计决定的可能原因是什么? 什么是实现我的目标的最佳方法? 我能想到的最好的方法是在我的课程中包装Multimap方法,但这远非理想。

编辑:

一些用户指出了不允许继承的正当理由。 为了稍微扩展问题,我想指出几点。

  1. 如果不建议在公共API中继承,那么为什么Java自己的集合类不是最终的?

  2. 假设我广泛使用以下类:

LinkedHashMultimap <类<? 扩展BaseEntity>,BiConsumer <? 扩展BaseEntity,? extends Object >>

现在,这是一个满口。 如果我可以:

public class ConsumerMap extends LinkedHashMultimap<Class<? extends BaseEntity>, BiConsumer<? extends BaseEntity, ? extends Object>> {
}

然后我可以在我的代码中使用ConsumerMap而不是那个怪物。 我相信只有可读性才足以证明继承的合理性。

正如其他人所指出的,你应该更喜欢委托继承。

您想要实现所需类的目的是使用LinkedHashMultimap作为委托来扩展ForwardingSetMultimap 这是一个看起来如何的例子:

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
}

旁白:你问“如果在公共API中不推荐继承,那么Java自己的集合类怎么不是最终的呢?”

我认为答案基本上是错误的,而不是让Java自己的集合类final (注意:其中一些,特别是新的,实际上是final )。 正如@Mick Mnemonic所说,Josh Bloch(他设计了原始集合API)参与了Guava集合API的设计:Guava API的设计决策反映了从原始集合API中汲取的经验教训。

这些类的设计不是为了扩展 因为继承本质上打破了封装,所以当无法扩展类时,它会使API更清晰。 (这里的相关主题: 禁止在Java中继承的好理由?

您通常可以通过使用合成来解决此问题。

要回答您的后续问题:

关于Java Collections API,我认为有两种选择:像ArrayListHashMap这样的类被设计为扩展,或者这只是一个API设计缺陷。 我怀疑后者; 但是,在API发布后,无法恢复此设计选择。 也许只有AbstractList这样的抽象类应该被声明为非final的?

可能Guava团队认为像你提供的那些用例非常罕见,不值得为继承添加支持(YAGNI)。

Josh Bloch的演讲 - 他参与了Java API和Guava的设计 - 是关于这个主题的精彩演讲。

机会是:

  1. 将默认方法添加到Java 8中的接口 (您不能将其作为集合类型由Guava库定义),
  2. 扩展实现 (再次你不能,因为实现主要是最终的)
  3. 使用您想要的方法提供外部助手类

暂无
暂无

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

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