`
yangtsefisher
  • 浏览: 27000 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

复合优于继承

    博客分类:
  • Java
 
阅读更多

1. 继承破坏了封装性,换句话说,子类依赖于父类的实现细节。

 

需要进一步说明,这与方法调用不同,方法调用也依赖被调用的方法,但是并不依赖细节,也就是说,只要方法整体实现没有问题,方法调用就没有问题,但是继承很容易改变父类实现的细节(所以父类中能写成final尽量写成final),即使父类整体没有问题,也有可能因为子类细节实现不当,而破坏父类的约束。这使得继承具有脆弱性。

 

或者说,继承让子类很容易破坏影响父类的约束,父类约束的实现依赖子类的实现,并且,父类在他的后续版本中可以获得新的方法,而这个会对子类造成影响,虽然子类的代码没有变化,当初子类实现的时候也不知道未来的变化,显得很无辜。

 

Here, overriding is the root of evil.....

 

继承使得到的API限制在原始想重用的实现上,导致可变更性变差,限制了你的类的性能。

 

继承使得有了更多机会来暴露了类内部的细节,比如Properties p的例子,p.getProperty(String key),p.get(String key)。

 

继承很容易传播现有API内部的缺陷。

 

2. 为什么复合/转发在做到重用的同时,不会有上述问题?

a. 通过接口,抓住需要重用类的功能特性,同时还获得了灵活性,继承只能重用某一个具体类的代码,但复用利用接口,可以重用很多接口类的代码。

b. 组合模式,包装类,也正是利用了这一点,获得了灵活性。

c. 缺点:转发方法调用的性能影响(可以忽略),包装对象导致的内存占用(这个在敏感的地方显得很重要,因为复用会导致产生更多的对象。子类扩展属性的时候,如果继承的话,就只有属性本身内存的增加,如果复用的话,还需另外加一个属性宿主自身以及宿主引用的内存增加)

 

3. 什么时候用继承合适:当确实存在"is-a"关系的时候。

 

 

 

参考:

《Effective Java》第四章,第14条

分享到:
评论

相关推荐

    编写高效优雅Java程序Java系列2021.pdf

    - **复合优于继承**:复合避免了子类对父类实现的依赖,增强了设计的灵活性和封装性。 - **接口优于抽象类**:Java支持单一继承,但可以实现多个接口。当业务变化时,更适合通过增加接口来实现,而不是修改抽象类...

    JVM与性能优化知识点整理.pdf

    3. 通用程序设计涉及复合优于继承、接口优于抽象类等面向对象的设计原则。 性能优化是一个全面考虑的过程: 1. 常用的性能评价/测试指标包括响应时间、并发数、吞吐量及其关系。 2. 常用的性能优化手段包括避免过早...

    编写高效优雅Java程序.docx

    在设计时,复合通常优于继承,因为继承可能导致封装性的破坏和对父类实现的依赖。接口优于抽象类,因为Java仅支持单继承,接口可以实现多态,而抽象类可能导致不需要改变的类被迫实现新的业务方法。JDK中经常采用...

    swift菜鸟入门视频教程-09-类和结构体

    4. 结构体比类更轻量级:由于结构体没有继承和引用计数,它们在内存管理和性能上通常优于类。 在选择使用类还是结构体时,应考虑以下几个因素: - 如果你需要的是一个拥有复杂生命周期的对象,或者需要继承和多态,...

    编写高效优雅Java程序.pdf

    5. 复合优先于继承:复合可以避免继承的缺陷,如破坏封装性和依赖于父类的实现。 6. 接口优于抽象类:接口可以提供更加灵活的设计方式,可以使得类更加灵活和可扩展。 7. 谨慎使用可变参数:可变参数可以使代码...

    【JVM和性能优化】4. 编写高效优雅Java代码常用方法

    优先使用复合胜过继承8.接口优于抽象类9. 可变参数谨慎使用10. 尽量不要返回NULL,尽量返回零数组或集合11.优先使用标准异常12.尽量使用枚举替换int13. 局部变量作用域最小化14. 对于精度技术不用float或double15....

    springboot常见经典面试题.docx

    - **简化配置**:Spring Boot 使用约定优于配置的方式,大量减少了 XML 配置,甚至无需编写任何配置文件,只需少量的 YAML 或 properties 配置。 - **自动配置**:Spring Boot 会根据项目中的依赖自动配置相应的 ...

    面向对象基本原则 面向对象基本原则

    例如,通过组合,我们可以创建一个包含多个不同功能的类的复合体,而不需要这些功能之间存在继承关系。 以上原则为面向对象设计提供了坚实的理论基础,它们共同构成了面向对象编程语言中最重要的设计理念之一。遵循...

    探讨 [源代码]C#类与结构体究竟谁快

    在C#编程语言中,类(Class)和结构体(Struct)是两种基本的复合数据类型,它们在很多方面有着显著的区别,这些区别直接影响到它们的性能表现。本篇文章将深入探讨C#中的类和结构体,以及它们在速度上的差异。 ...

    高质量C++编程指南

    - **第4章 表达式和基本语句**:探讨运算符优先级、复合表达式、条件语句、循环语句等。 - **第5章 常量**:解释常量的必要性、`const`与`#define`的对比等。 - **第6章 函数设计**:讨论参数、返回值、函数实现规则...

    双相不锈钢性能及锻造PPT课件.pptx

    双相不锈钢的机械性能显著,它继承了奥氏体不锈钢的高塑性和韧性,同时克服了奥氏体不锈钢的室温脆性,减少了475°C脆性的问题。与传统奥氏体不锈钢相比,双相不锈钢的强度更高,抗晶间腐蚀和氯化物应力腐蚀的能力也...

    Ruby基础教程

    继承(Inheritance)允许子类继承父类的属性和方法,从而实现代码复用。Ruby还引入了模块(Module),用于封装代码,提供命名空间和混合(Mixins)功能,让类可以“混入”其他模块的方法。 在Web开发领域,Ruby最...

    ruby语言基础

    数据类型包括基本类型(如整型、浮点型、字符串、布尔型)和复合类型(如数组、哈希、范围和符号)。 2. **控制结构**:Ruby提供了if/else、unless、case、循环(for、while、until)等控制流语句,以及begin/...

    C++程序编码规范(程序员必备)

    - 组合通常优于继承。 #### 十二、其他规范及建议 ##### 1. 提高程序的效率 - 优化算法和数据结构。 - 使用高效的容器类型。 ##### 2. 一些有益的建议 - 编写单元测试以确保代码的质量。 - 保持代码的一致性和...

Global site tag (gtag.js) - Google Analytics