为什么不是 Guava ImmutableCollections 接口?
Why aren't Guava ImmutableCollections interfaces?
Guava 的 ImmutableCollection
有像 ImmutableList
这样的子 classes,它们是(不可扩展的)抽象 classes 而不是接口。 documentation 表示这是为了防止外部子类型化。另一方面,文档还说他们
should be thought of as interfaces in every important sense
但是外部子类型化的能力不是接口的重要意义吗?例如,如果 ImmutableList
是一个接口,我可以有一个像
这样的方法签名
public ImmutableList<String> getNames();
(正如 Guava 推荐的那样),然后可以在将来灵活地交换 ImmutableList
的自定义实现。然而,由于实际上它是一个抽象的 class,我没有这种灵活性,因此只能使用 Guava 的实现。因此,如果我想保持这种灵活性,我将不得不恢复使用更通用的 return 类型 List
,它不再向调用者传达有关不变性的有用信息:
public List<String> getNames();
那么为什么不对这些进行外部子类型化很重要?一个答案可能是 Guava 设计者不信任外部实现者来正确支持所需的语义,但 List
本身实际上有相当广泛的合同,并且没有人阻止它的自定义实现。还是有其他原因?
这是因为如果它是一个接口,就没有办法让 ImmutableList
类型保证不变性。
不,我不认为任何人都能够编写自己的 interface
实现是所有接口的必要条件 属性。例如,考虑密封类型,它只允许在同一文件中定义的一组特定实现。它们仍然可以是 interface
s(有一个提案包括 sealed interface
for Java here),不允许世界上任何人创建它们的实现。
我也很好奇为什么您认为您可能想要自己的自定义实现一些超级简单的东西,比如不可变列表。
Guava 的 ImmutableCollection
有像 ImmutableList
这样的子 classes,它们是(不可扩展的)抽象 classes 而不是接口。 documentation 表示这是为了防止外部子类型化。另一方面,文档还说他们
should be thought of as interfaces in every important sense
但是外部子类型化的能力不是接口的重要意义吗?例如,如果 ImmutableList
是一个接口,我可以有一个像
public ImmutableList<String> getNames();
(正如 Guava 推荐的那样),然后可以在将来灵活地交换 ImmutableList
的自定义实现。然而,由于实际上它是一个抽象的 class,我没有这种灵活性,因此只能使用 Guava 的实现。因此,如果我想保持这种灵活性,我将不得不恢复使用更通用的 return 类型 List
,它不再向调用者传达有关不变性的有用信息:
public List<String> getNames();
那么为什么不对这些进行外部子类型化很重要?一个答案可能是 Guava 设计者不信任外部实现者来正确支持所需的语义,但 List
本身实际上有相当广泛的合同,并且没有人阻止它的自定义实现。还是有其他原因?
这是因为如果它是一个接口,就没有办法让 ImmutableList
类型保证不变性。
不,我不认为任何人都能够编写自己的 interface
实现是所有接口的必要条件 属性。例如,考虑密封类型,它只允许在同一文件中定义的一组特定实现。它们仍然可以是 interface
s(有一个提案包括 sealed interface
for Java here),不允许世界上任何人创建它们的实现。
我也很好奇为什么您认为您可能想要自己的自定义实现一些超级简单的东西,比如不可变列表。