`

组合优于继承

阅读更多
面向对象系统中功能复用的两种最常用技术是类继承和对象组合(object composition)。正如我们已解释过的,类继承允许你根据其他类的实现来定义一个类的实现。这种通过生成子类的复用通常被称为白箱复用(white-box reuse)。术语“白箱”是相对可视性而言:在继承方式中,父类的内部细节对子类可见。

    对象组合是类继承之外的另一种复用选择。新的更复杂的功能可以通过组装或组合对象
来获得。对象组合要求被组合的对象具有良好定义的接口。这种复用风格被称为黑箱复用
(black-box reuse),因为对象的内部细节是不可见的。对象只以“黑箱”的形式出现。继承和组合各有优缺点。类继承是在编译时刻静态定义的,且可直接使用,因为程序设计语言直接支持类继承。类继承可以较方便地改变被复用的实现。当一个子类重定义一些而不是全部操作时,它也能影响它所继承的操作,只要在这些操作中调用了被重定义的操作。但是类继承也有一些不足之处。首先,因为继承在编译时刻就定义了,所以无法在运行时刻改变从父类继承的实现。更糟的是,父类通常至少定义了部分子类的具体表示。因为继承对子类揭示了其父类的实现细节,所以继承常被认为“破坏了封装性” [ S n y 8 6 ]。子类中的实现与它的父类有如此紧密的依赖关系,以至于父类实现中的任何变化必然会导致子类发生变化。

    当你需要复用子类时,实现上的依赖性就会产生一些问题。如果继承下来的实现不适合
解决新的问题,则父类必须重写或被其他更适合的类替换。这种依赖关系限制了灵活性并最终限制了复用性。一个可用的解决方法就是只继承抽象类,因为抽象类通常提供较少的实现。对象组合是通过获得对其他对象的引用而在运行时刻动态定义的。组合要求对象遵守彼此的接口约定,进而要求更仔细地定义接口,而这些接口并不妨碍你将一个对象和其他对象一起使用。这还会产生良好的结果:因为对象只能通过接口访问,所以我们并不破坏封装性;只要类型一致,运行时刻还可以用一个对象来替代另一个对象;更进一步,因为对象的实现是基于接口写的,所以实现上存在较少的依赖关系。

    对象组合对系统设计还有另一个作用,即优先使用对象组合有助于你保持每个类被封装,并被集中在单个任务上。这样类和类继承层次会保持较小规模,并且不太可能增长为不可控制的庞然大物。另一方面,基于对象组合的设计会有更多的对象 (而有较少的类),且系统的行为将依赖于对象间的关系而不是被定义在某个类中。

这导出了我们的面向对象设计的第二个原则:
    优先使用对象组合,而不是类继承。
分享到:
评论

相关推荐

    10丨理论七:为何说要多用组合少用继承?如何决定该用组合还是继承?1

    其中,“组合优于继承”是一条广为流传的原则,意味着在设计软件时,我们应该优先考虑使用组合(Composition)而不是继承(Inheritance)。这条原则的提出主要是为了解决继承带来的潜在问题,如代码的可维护性、可...

    面向对象七大原则

    面向对象编程的七大原则是指在面向对象设计中所遵循的七个基本原则,它们是:开闭原则、依赖倒转原则、单一职责原则、接口隔离原则、迪米特法则、里氏替换原则和组合优于继承原则。 1. 开闭原则(Open-Closed ...

    编程语言中的架构思考-姚钢强.pdf

    在讨论编程原则时,姚钢强提出了“组合优于继承(Composition over Inheritance)”的思想。继承是一种常见的面向对象编程(OOP)特性,允许一个类(子类)从另一个类(父类)继承属性和方法。然而,过度依赖继承...

    软件设计与架构原理及模式指南

    介绍了继承、多态等OOP基本原则及封装特性,讨论了组合优于继承的设计原则。 适合人群:对于希望提升代码质量和系统设计水平的研发人员。 使用场景及目标:帮助软件开发者掌握良好的编码习惯,理解不同的编程范式,...

    【IT十八掌徐培成】Java基础第04天-04.OOP-堆栈的溢出与设置-private关键字.zip

    4. 组合优于继承:在设计原则中,"组合优于继承"提倡使用组合而非继承来实现功能扩展。`private`成员可以使得子类无法直接访问,从而鼓励使用组合,避免因继承而带来的复杂性和脆弱性。 总之,理解和掌握堆栈溢出的...

    面向对象设计原则.pdf

    通过对比两个设计示例,我们可以看到,在第一个示例中,使用组合优于继承,因为在“人”扮演多种角色的情况下,继承会导致转化和角色混淆。而在第二个示例中,由于“乘客”和“代理人”是人所扮演的具体角色,且不会...

    java高级面试题集

    组合优于继承 "组合优于继承"是一种设计原则,这句话的意思是说,在设计类时,使用组合关系代替继承关系。继承关系使得子类紧密耦合于父类,限制了子类的灵活性和扩展性,而组合关系使得类之间松耦合,提高了系统的...

    EntityComponentSystemSamples-master.zip

    其模式遵循组合优于继承原则,游戏内的每一个基本单元都是一个实体,每个实体又由一个或多个组件构成,每个组件仅仅包含代表其特性的数据(即在组件中没有任何方法)。系统便是来处理拥有一个或多个相同组件的实体...

    50丨装饰器模式:通过剖析JavaIO类库源码学习装饰器模式1

    通过这种方式,装饰器模式在不破坏原有类结构的前提下,提供了一种优雅地扩展对象功能的方法,避免了使用继承带来的问题,遵循了“组合优于继承”的设计原则。 总结来说,装饰器模式是Java IO类库设计中的关键,它...

    C#抽象类和接口的区别.docx

    4. **组合优于继承**:在设计时,优先考虑对象组合(组合复用),而不是过多地使用继承,以避免类层次过深导致的问题。 总之,抽象类和接口都是C#中实现抽象和多态的重要手段,它们各有优势,适用于不同的场景。在...

    经典讲座系列重构之美ppt文档

    同时,提倡惯例优于配置和组合优于继承的准则,强调通过合理的组合来构建模块,以降低代码耦合度。 重构之美不仅体现在代码的结构优化上,还体现在对开发流程和团队协作的影响。通过不断的重构,开发团队可以持续...

    C#接口与抽象类的详解

    10. 使用对象组合(组合优于继承)可以避免过多的继承层次,减少内存开销和复杂性。 在实际开发中,选择抽象类还是接口取决于具体需求。如果预计未来会有多个版本的组件,抽象类是不错的选择,因为它提供版本控制的...

    Java高效编程指南.doc

    - **组合优于继承**:优先考虑使用组合而不是继承,因为继承可能导致紧耦合和难以维护的代码结构。只有在必须扩展类行为时才使用继承。 - **接口与抽象类**:接口提供了一种定义规范的方式,而抽象类可以提供部分...

    设计模式系列之装饰模式

    2. 组合优于继承:通过组合多个装饰器,可以实现更复杂的行为,而继承可能导致类的层次结构过于庞大和难以管理。 3. 高度解耦:装饰模式将组件与装饰者职责分离,使得两者可以独立发展,增强了系统的可维护性和可...

    Java选择题.pdf

    A选项描述的是类的继承关系,B选项涉及对象的组合(组合优于继承),都不是多态性的直接定义。 在Java中,子类可以继承父类,并可以向上转型。题目中的第六题展示了这种转换。A、B和D选项都是正确的,但C选项错误,...

    经典C和C++面试题.pdf

    组合优于继承,是因为继承会使得类之间的关系变得复杂。多态的基础是继承,没有继承就没有多态。 4. 指针和引用: 指针和引用都是C++中的基本概念。引用在创建时必须初始化,不能为空引用;指针可以为空指针。引用...

    JAVAjiangyi

    - 组合优于继承,因为它保持了类的独立性,提高了代码的灵活性和可维护性。 7. **final关键字**: - `final`修饰变量,使其成为常量,不可修改。 - 修饰方法,防止子类重写,但可以重载。 - 修饰类,表示该类不...

    Java软件开发实战 Java基础与案例开发详解 7-1 面向对象的分析与设计简介 共11页.pdf

    - **组合优于继承**:使用组合而不是继承来复用代码。 **5.2 命名规范** - **类名**:首字母大写,其他单词首字母大写(CamelCase)。 - **变量名**:首字母小写,其他单词首字母大写(camelCase)。 - **方法名**...

    OO设计原则总结.doc

    #### 组合优于继承:Favor Composition Over Inheritance 尽管继承在某些场景下非常有用,但它也可能带来不必要的耦合和复杂性。组合原则提倡通过对象组合而非继承来实现代码复用。组合的优点包括: - **减少耦合*...

Global site tag (gtag.js) - Google Analytics