为啥 Adapter 会从 Target 公开继承,而从 Adapter 私下继承?

Posted

技术标签:

【中文标题】为啥 Adapter 会从 Target 公开继承,而从 Adapter 私下继承?【英文标题】:Why Adapter would inherit publicly from Target and privately from Adaptee?为什么 Adapter 会从 Target 公开继承,而从 Adapter 私下继承? 【发布时间】:2014-04-04 10:42:22 【问题描述】:

“DesignPatterns: Elements of Reusable Object-Oriented Software”一书中谈到Adapter模式的C++实现时,是这样的:

[...] 在类适配器的 C++ 实现中,Adapter 将公开继承自 Target,私下继承自 Adaptee。 [...]

有人能解释一下这里的原因吗?

【问题讨论】:

在我看来,一切都是关于抽象的。 Adapter 可以直接Adaptee 交互,但它不能成为其他类与Adaptee 交互的代理。也许给this article 一次可能会提供更清晰的画面。 【参考方案1】:

在面向对象的编程中,对象类之间的关系可以分为“is-a”、“has-a”或“is-implemented-in-terms-of”。

对于 C++,“is-a”关系可以(并且应该)通过公共继承来实现。

Has-a”可以(并且应该)通过遏制来实施。它使 using 类仅依赖于 used 类的公共部分。在极少数情况下,作为最后的手段,您可能希望通过非公共继承来实现“has-a”,但这通常表明设计不佳。

Is-implemented-in-terms-of”可以通过包含或非公共继承来实现。

非公共继承允许你访问使用的类的受保护部分,覆盖它的虚方法等。它也有助于其他人更好地理解你的意图(只要非公共继承表达“is-implemented-in”) -terms-of”和containment表示“has-a”)。

另一方面,收容有其自身的一些优势。例如,它允许拥有所用类的多个实例。它还允许我们实现依赖注入,从而满足依赖倒置原则。

Adapter “is-a” 子类型的 Target,同时也是“is-implemented-in-terms-of” Adaptee。 因此 Adapter 应该从 Target 公开继承。 但是您可以使用私有继承或包含来实现 Adapter 和 Adaptee 之间的“is-implemented-in-terms-of”关系。

用于决定使用哪种类型的关系的主要标准之一是您要实现的适配器模式的类型(类适配器或对象适配器)。

【讨论】:

以上是关于为啥 Adapter 会从 Target 公开继承,而从 Adapter 私下继承?的主要内容,如果未能解决你的问题,请参考以下文章

如果'C'从'B'公开继承,B私下从'A'继承,为啥我不能在'C'内部创建'A'的对象? [复制]

Adapter (适配器模式)

面试题-Java设计模式举例

七适配器(Adapter)模式--结构模式(Structural Pattern)

java design pattern - adapter pattern

为啥继承的受保护运算符=()具有公共访问权限