🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
## 一、继承的问题 >我们知道Java的三大特性:封装,继承,多态。Java 继承有很多优点,是减少重复代码的可靠手段。 但是继承同时存在一些`缺点`: 1.类的耦合性增加了。比如父类更改之后子类也同时需要更改 2.降低代码灵活性。因为继承时,父类会对子类有约束性 我们使用`里氏替换原则`,可以减少继承带来的问题。 ## 二、定义 ``` 里氏替换原则(LSP)指的是所有引用基类的地方都可以透明的使用其子类的对象 可以理解为:只要有父类出现的地方,都可以使用子类来替代。而且不会出现任何错误或者异常。 但是反过来却不行。子类出现的地方,不能使用父类来替代。 如果不符合上述的规定的话,我们可以想象子类的实例化调用方法时候,调用的却是父类的方法。 会出现意想不到的结果 ``` ## 三、具体约束 1. 子类必须实现父类的抽象方法,但不得重写父类的非抽象(已实现的)方法。 2. 子类中可增加自己特有的方法。(可以随时扩展) 3. 当子类覆盖或者实现父类的方法时,方法的前置条件(方法形参)要比父类输入参数更加宽松。 否则会调用到父类的方法。 4. 当子类的方法实现父类的抽象方法时,方法的后置条件(即方法的返回值)要比父类更严格。 否则会调用到父类的方法。 >在讲开闭原则的时候埋下了一个伏笔,在获取折扣时重写覆盖了父类的 getPrice() 方法,增加了一个获取原价的方法 getOriginPrice(),显然就违背了里氏替换原则。我们修改一下代码,不应该覆盖 getPrice() 方法,增加 getDiscountPrice() 方法: ~~~ public class JavaDiscountCourse extends JavaCourse { public JavaDiscountCourse(Integer id, String name, Double price) { super(id, name, price); } public Double getDiscountPrice() { return super.getPrice() * 0.61; } } ~~~ >里氏替换原则只存在于父类与子类之间,约束继承泛滥 ## 四、最佳实践 >我们最好将父类定义为抽象类,并定义抽象方法,让子类重新定义这些方法, 当父类是抽象类时候,父类不能实例化