java - 如何在运行时替换对象组合的实现(接口(interface)继承)

标签 java

我遇到了以下几点对象组合相对于类继承的优势。但是我经常在很多文章中看到下面这句话

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,你将不得不有两个类:ArrayListStackLinkedListStack。 (这种方法也有一个缺点,即在 Stack 上暴露了 List 方法,这违反了封装)。

如果您改用组合,List 可以由调用者提供以支持 Stack,并且您可以拥有一个 Stack 类可以采用 LinkedListArrayList,具体取决于用户所需的运行时特性。

简而言之,实现“在运行时更改”的能力不是指类的实例能够在运行时更改其实现,而是类确实在编译时不知道它的精确实现是什么。

另请注意,使用组合的类不需要允许在运行时(由调用者)选择委托(delegate)实现。有时这样做会违反封装,因为它会给调用者提供比期望更多的关于类内部的信息。在这些情况下,组合仍然具有仅公开抽象方法的好处,并允许在以后的修订中更改具体实现。

现实生活中的例子

顺便说一下,我使用 Stack 的例子是因为它不是纯粹的假设。 Java's Stack class实际上扩展了 Vector,这使得它永远承载着同步的包袱和数组支持列表的性能特征。因此,强烈建议不要使用该类。

正确使用集合组合的完美示例也可以在 Java 库中找到,位于 Collections.newSetFromMap(Map) 中。 .由于任何 Map 都可以用来表示一个 Set(通过使用虚拟值),此方法返回一个 Set composed 传入的 Map。返回的 Set 然后继承了它包装的 Map 的特性,例如:可变性、线程安全和运行时性能——所有这些都无需创建并行 Set ConcurrentHashMapImmutableMapTreeMap 等的实现

关于java - 如何在运行时替换对象组合的实现(接口(interface)继承),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16370937/

相关文章:

java - 如何阻止 JTextArea 和 JTextField 拉伸(stretch)?

java - 无法解析此 json 字段

java - Nim 游戏示例静态和随机问题

java - ORM如何映射到接口(interface)?

java - 如何删除或更新 ObservableList 中的某些行

java - 在 lucene 中使最新内容相关的技术有哪些?

java - Android 什么是命名也执行逻辑的 boolean 函数的最佳方式?

java - ids 无法解析或不是字段

java - 如何同时从两个服务读取值

java - 使用 WireMock 我们如何验证给定 url 的请求尚未发出?