我遇到了以下几点对象组合相对于类继承的优势
。但是我经常在很多文章中看到下面这句话
In object composition, functionality is acquired dynamically at run-time by objects collecting references to other objects. The advantage of this approach is that implementations can be replaced at run-time. This is possible because objects are accessed only through their interfaces, so one object can be replaced with another just as long as they have the same type.
但怀疑可能是天真的,因为我是初学者。如何在运行时替换实现?如果我们写了一行新代码,难道我们不需要编译来反射(reflect)变化吗?那么运行时替换
是什么意思呢?相当困惑。
或者任何其他魔术,幕后 Activity 都会发生。任何人都可以请回复。
最佳答案
想想 Stack
的实现。 Stack
的简单实现在幕后利用了 List
。如此天真,您可以扩展 ArrayList
。但是现在如果你想要一个由 LinkedList
支持的单独的 Stack
,你将不得不有两个类:ArrayListStack
和 LinkedListStack
。 (这种方法也有一个缺点,即在 Stack
上暴露了 List
方法,这违反了封装)。
如果您改用组合,List
可以由调用者提供以支持 Stack
,并且您可以拥有一个 Stack
类可以采用 LinkedList
或 ArrayList
,具体取决于用户所需的运行时特性。
简而言之,实现“在运行时更改”的能力不是指类的实例能够在运行时更改其实现,而是类确实在编译时不知道它的精确实现是什么。
另请注意,使用组合的类不需要允许在运行时(由调用者)选择委托(delegate)实现。有时这样做会违反封装,因为它会给调用者提供比期望更多的关于类内部的信息。在这些情况下,组合仍然具有仅公开抽象方法的好处,并允许在以后的修订中更改具体实现。
现实生活中的例子
顺便说一下,我使用 Stack 的例子是因为它不是纯粹的假设。 Java's Stack class实际上扩展了 Vector
,这使得它永远承载着同步的包袱和数组支持列表的性能特征。因此,强烈建议不要使用该类。
正确使用集合组合的完美示例也可以在 Java 库中找到,位于 Collections.newSetFromMap(Map)
中。 .由于任何 Map
都可以用来表示一个 Set
(通过使用虚拟值),此方法返回一个 Set
composed 传入的 Map
。返回的 Set
然后继承了它包装的 Map
的特性,例如:可变性、线程安全和运行时性能——所有这些都无需创建并行 Set
ConcurrentHashMap
、ImmutableMap
、TreeMap
等的实现
关于java - 如何在运行时替换对象组合的实现(接口(interface)继承),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16370937/