java - 有效的 Java : Safety of Forwarding Classes

标签 java inheritance guava composition effective-java

Effective Java 3rd Edition,第 18 项:Favor composition over inheritance 描述了使用继承向类添加行为的问题:

A related cause of fragility in subclasses is that their superclass can acquire new methods in subsequent releases. Suppose a program depends for its security on the fact that all elements inserted into some collection satisfy some predicate. This can be guaranteed by subclassing the collection and overriding each method capable of adding an element to ensure that the predicate is satisfied before adding the element. This works fine until a new method capable of inserting an element is added to the superclass in a subsequent release. Once this happens, it becomes possible to add an "illegal" element merely by invoking the new method, which is not overridden in the subclass.

推荐的解决方案:

Instead of extending an existing class, give your new class a private field that references an instance of the existing class... Each instance method in the new class invokes the corresponding method on the contained instance of the existing class and returns the results. This is known as forwarding, and the methods in the new class are known as forwarding methods... adding new methods to the existing class will have no impact on the new class... It's tedious to write forwarding methods, but you have to write the reusable forwarding class for each interface only once, and forwarding classes may be provided for you. For example, Guava provides forwarding classes for all of the collection interfaces.

我的问题是,方法是否也可以添加到转发类,从而破坏子类的不变量,这样的风险是否仍然存在?像 Guava 这样的外部库如何在不冒其客户端完整性风险的情况下将更新的方法合并到转发类中?

最佳答案

默认的假设似乎是 是编写转发类的人,因此您可以控制是否向其中添加任何内容。无论如何,这是使用组合而不是继承的常见方式。

Guava 例子好像是指the Forwarding Decorators ,它们被明确设计为从中继承。但它们只是 helper ,使创建这些转发类变得更简单,而不必在接口(interface)中定义每个方法;它们明确地不会使您免受将来添加的您可能还需要覆盖的任何方法的影响:

Remember, by default, all methods forward directly to the delegate, so overriding ForwardingMap.put will not change the behavior of ForwardingMap.putAll. Be careful to override every method whose behavior must be changed, and make sure that your decorated collection satisfies its contract.

所以,如果我理解正确的话,Guava 并不是一个很好的例子。

关于java - 有效的 Java : Safety of Forwarding Classes,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49379208/

相关文章:

java - Guava Optional 作为可选参数的方法参数

java - 如何在 ZigZag 路径中​​遍历和打印二维数组

java - 最大值是多少?字节数组的容量?

C++ 从接口(interface)类到子类的无效转换

c++ 使用基本类型作为基类

Java、谷歌集合库; AbstractIterator 的问题?

java - 从对象列表到基于 Java 8 或 Guava 的键和值对对象进行分组

java - 获取所有联系人时出错

java - Java 的 WordPress url 重写

c++如何在派生类中实现常量静态成员