组合优于继承
面向对象设计的过程中, 两个最常用的技巧就是类继承和对象组合,同一个场景下的代码复用,这两个技巧基本上都可以完成。 但是他们有如下的区别:
- 通过继承实现的代码复用常常是一种“白盒复用”, 这里的白盒指的是可见性: 对于继承来说,父类的内部实现对于子类来说是不透明的(实现一个子类时, 你需要了解父类的实现细节, 以此决定是否需要重写某个方法)
- 对象组合实现的代码复用则是一种“黑盒复用”“: 对象的内部细节不可见,对象仅仅是以“黑盒”的方式出现(可以通过改变对象引用来改变其行为方式)
继承(Inheritance)的问题
- ❌ 强耦合:子类依赖父类,修改父类影响所有子类。
- ❌ 扩展性差:Java 不支持多继承,代码僵硬。
- ❌ 违反 Liskov 替换原则(LSP):子类可能改变父类行为,导致不一致。
- ❌ 继承层次过深:难以维护,父类变动影响所有子类。
组合(Composition)的优势
- ✅ 低耦合:各组件独立,修改不影响其他类。
- ✅ 高灵活性:可以在运行时动态改变行为。比如动态传入一个新对象,可以运行时改变行为。
- ✅ 代码复用:避免继承层次过深,代码更易维护。
- ✅ 遵循开闭原则(OCP):扩展新功能无需修改原有代码。