别再使用继承了,除非你想要交点税

别再使用继承了,除非你想要交点税
最新回答
校园若塌,便是晴天

2021-11-29 17:27:32

应尽量避免使用继承,因其会导致耦合并带来一系列问题,推荐使用接口、委托、特性/混合等替代方案。具体分析如下:

使用继承存在的问题
  • 继承导致耦合

    共享代码时子类与父类耦合:当程序员为共享代码让一系列类继承同一个Base类时,子类和父类紧密耦合。若父类修改,所有子类都会受影响。例如,父类增加或修改方法、属性,子类可能需相应调整,否则可能出现兼容性问题,增加维护难度和出错风险。

    表示类关系时继承方式受限:以猫为例,从生物领域分类有界门纲目科属种等层级,如猫科、哺乳纲;从其他方向看,它可以是宠物、资产、食物等。现有继承方式,尤其是大部分编程语言不支持多继承(如Java),难以准确完整表达类的复杂关系,可能形成错综复杂的网状结构,而非清晰的树状结构。

继承的替代方案
  • 接口

    解决多重继承问题:在Java等语言中,接口可实现类似多重继承功能。如车要同时有定位和驾驶功能,可定义两个接口,车类实现这两个接口,避免因语言不支持多继承而受限。

    使组合更灵活:车类与定位、驾驶功能类通过接口实现松耦合,这两个功能类可被其他类复用。如手机实现定位接口,车和手机可放入同一List实现多态,提高代码复用性和可扩展性。

    示例

  • 委托

    避免继承不必要功能:继承可能让子类强制拥有父类众多方法,如父类有20个方法,子类只需3个,却继承了全部,导致对类行为控制力下降。委托可将某些工作交给专门类,如让类持久化时调用持久化类功能。

    进一步优化解耦:以账户类为例,它无需知道如何持久化,只需关注业务。可建包装类实现持久化功能,使账户与持久化彻底解耦,但需编写更多代码。对于通用功能,如查询功能,为每个类写包装类成本较高。

    示例

  • 特性/混合(Mixin)

    实现类或对象扩展:在不使用继承前提下对类或对象扩展,不同语言叫法不同,Java无此特性。它可看作与语言无关方案,如定义公共查询类,让需要类混合。

    语言支持情况:以Scala语言为例,有用于trait(特性)的extends...with用法。若语言本身不支持,如Java,可利用新加的default关键字实现低配版Mixin,如在接口中使用default给方法定义默认实现,但无法完全实现Mixin所有特性,如实现多个接口有同一方法时,实现类必须重写该方法。

    示例