继承:

优点

● 代码 共享, 减少 创建 类 的 工作量, 每个 子类 都 拥有 父 类 的 方法 和 属性;
● 提高 代码 的 重用 性;
● 子类 可以 形似 父 类, 但又 异于 父 类,“ 龙 生 龙, 凤 生 凤, 老鼠 生来 会 打洞” 是说 子 拥有 父 的“ 种”,“ 世界上 没 有两 片 完全 相同 的 叶子” 是 指明 子 与 父 的 不同;
● 提高 代码 的 可 扩展性, 实现 父 类 的 方法 就可以“ 为所欲为” 了, 君 不见 很多 开源 框架 的 扩展 接口 都是 通过 继承 父 类 来 完成 的;
● 提高 产品 或 项目 的 开放 性。
. 设计模式之禅(第2版)

缺点

  1. 继承 是 侵入 性的。 只要 继承, 就必须 拥有 父 类 的 所有 属性 和 方法;
  2. 降低 代码 的 灵活性。 子类 必须 拥有 父 类 的 属性 和 方法, 让 子类 自由 的 世界 中 多了 些 约束;
  3. 增强 了 耦合 性。 当 父 类 的 常量、 变量 和 方法 被 修改 时, 需要 考虑 子类 的 修改, 而且 在 缺乏 规范 的 环境 下, 这种 修改 可能 带来 非常 糟糕 的 结果—— 大段 的 代码 需要 重 构。

解决多继承带来的弊大于利的解决方法

氏 替换 原则( Liskov Substitution Principle, LSP)

什么 是 里 氏 替换 原则 呢?

定义1:
如果 对 每一个 类型 为 S 的 对象 o1, 都有 类型 为 T 的 对象 o2, 使得 以 T 定义 的 所有 程序 P 在 所有 的 对象 o1 都 代换 成 o2 时, 程序 P 的 行为 没有 发生 变化, 那么 类型 S 是 类型 T 的 子 类型。
定义2:
所有 引用 基 类 的 地方 必须 能 透明 地 使用 其 子类 的 对象。
只要 父 类 能 出现 的 地方 子类 就可以 出现, 而且 替换 为 子类 也不 会 产生 任 何 错误 或 异常, 使用者 可能 根本 就不 需要 知道 是 父 类 还是 子类。 但是, 反过来 就不 行了, 有 子类 出现 的 地方, 父 类 未必 就能 适应。

要求:

  1. 子类 必须 完全 实现 父 类 的 方法
    我们 在做 系统 设计 时, 经常 会 定义 一个 接口 或 抽象 类, 然后 编码 实现, 调用 类 则 直接 传入 接口 或 抽象 类, 其实 这里 已经 使 用了 里 氏 替换 原则。