里氏替换原则:
核心精神:
在使用基类的的地方可以任意使用其子类,能保证子类完美替换基类;
这一精神其实是对继承机制约束规范的体现。
在父类和子类的具体实现中,严格控制继承层次中的关系特征,以保证用子类替换基类时,程序行为不发生问题,且能正常进行下去。
里氏替换原则主要发力点是继承基础上的抽象和多态,具体就是子类必须实现父类的方法,是重写;
这里要注意重写(Override)与重载(Overload)的区分,
即使参数的数据范围发生变化,也能将重写变成重载!
而你原本只是想把所继承的方法完善的具体点儿!如果是这样的话绝对会引起以后业务逻辑的混乱。
里氏替换原则是关于继承机制的设计原则,违反里氏替换原则将会使继承变的一塌糊涂;而遵循里氏替换原则能够保证系统具有良好的的拓展性,我们可以随时根据需要增改不同的子类,这将大大增强程序的健壮性,让版本的升级可以做到非常好的兼容;同时基于多态的抽象机制,能够很好的减少代码冗余,避免运行期的类型判别等;而在项目的实施中不同的子类对应着不同的业务,使用父类做参数,不同子类可以轮番上阵,必然强大!
回顾下【重写(Override)与重载(Overloaded)】
多态性是面向对象编程的一种特性,和方法本身无关。
方法的重载,就是同样的一个方法能够根据输入数据的不同,做出不同的处理——有不同的参数列表,甚至不同的返回值(静态多态性)
方法的在重写,是子类继承自父类的相同方法,输入参数一样,但要做出有别于父类的操作,要覆盖父类方法。——相同参数,相同返回值,不同实现(动态多态性)
用好重写和重载可以设计一个结构清晰而简洁的类,重写和重载在编写代码过程中的作用非同凡响。
肯定有不少人跟我刚看到这项原则的时候一样,对这个原则的名字充满疑惑。其实原因就是这项原则最早是在1988年,由麻省理工学院的一位姓里的女士(Barbara Liskov)提出来的。
定义1:如果对每一个类型为 T1的对象 o1,都有类型为 T2 的对象o2,使得以 T1定义的所有程序 P 在所有的对象 o1 都代换成 o2 时,程序 P 的行为没有发生变化,那么类型 T2 是类型 T1 的子类型。
定义2:所有引用基类的地方必须能透明地使用其子类的对象。
问题由来:有一功能P1,由类A完成。现需要将功能P1进行扩展,扩展后的功能为P,其中P由原有功能P1与新功能P2组成。新功能P由类A的子类B来完成,则子类B在完成新功能P2的同时,有可能会导致原有功能P1发生故障。
解决方案:当使用继承时,遵循里氏替换原则。类B继承类A时,除添加新的方法完成新增功能P2外,尽量不要重写父类A的方法,也尽量不要重载父类A的方法。
继承包含这样一层含义:父类中凡是已经实现好的方法(相对于抽象方法而言),实际上是在设定一系列的规范和契约,虽然它不强制要求所有的子类必须遵从这些契约,但是如果子类对这些非抽象方法任意修改,就会对整个继承体系造成破坏。而里氏替换原则就是表达了这一层含义。