里氏替换原则
一、什么是里氏替换原则
先在这里给大家说一下书本对于这一原则的定义:如果对每一个类型为S的对象o1,都有类
型为T的对象o2,使得以T定义的所有程序P在所有的对象o1代换o2时,程序P的行为没有变化,那么
类型S是类型T的子类型。这是Barbara Liskov教授与eannette Wing教授于1994年提出的一个比较
官方的定义,大家也知道这种学科界的大牛思想一般人很难理解。通俗点来讲就是:在继承关系中
,父类出现的地方子类也就能出现,并且将父类替换成子类,也不会改变来本的程序。其实他的特
点也是对于更变的抗性比较高。在里氏替换原则中有一点很重要的我们要注意:是父类能先出现的
地方,子类才能替换,反之子类能先出现的地方父类不一定能出现。
里氏替换原则的特点:
就是无论我们是用父类对象还是用子类对象都应该对程序没有任何影响。
二、里氏替换原则的规范
里氏替换原则是对继承进行契约规范,使其更适用于商业化。
规范:
1、子类必须完全实现父类的方法,如果子类要有自己的个性方法也是可以的,但是一定要在
父类中声明。为什么要这样呢?其实大家可以这样想,如果一个方法只存在子类中,在父类中不提
供相应的声明,则无法在以父类定义的对象中使用该方法。这样就不符合上面说的里氏替换原则的
特点。
2、当子类重载父类的方法是,子类的形参的范围要比父类的形参范围大。(这么设计的好处
会在后面进行详细分析)
三、里氏替换原则更变抗性的体现
在继承关系中,当子类与父类的方法发生重载是,可能出现的比较严重后果。我在此用两个例子进行对于,就能够很清晰的展露出里氏替换原则的特点:
例子一:以下是一简单程序的架构代码
public class Father { public Collection doSomething(Map map){ System.out.println("父类被执行..."); return map.values(); } class Son extends Father { //缩小输入参数范围 public Collection doSomething(HashMap map){ System.out.println("子类被执行..."); return map.values(); } }
以上是子类中重载父类的方法,并且参数范围是子类范围小于父类中的范围,我们来看看结果如何
public class Clinet { public static void main(String[] args) { //有父类的地方就有子类 Father f= new Father(); HashMap map = new HashMap(); f.doSomething(list); } }
这个是主程序入口,我们运行结果看一下: 父类被执行...
当我们根据里氏替换原则用子类的对象替换父类的对象再看一下结果
public class Clinet { public static void main(String[] args) { //有父类的地方就有子类 Son f =new Son(); HashMap map = new HashMap(); f.doSomething(list); } }
这个是主程序入口,我们运行结果看一下: 子类被执行...
从以上的两个例子进行对比,我们不难看出我们用了里氏替换原则后程序发生了变化,这样的变化是不允许的,也是不符合里氏替换原则的。
因此我们的有一个结论:当子类重载父类的方法时,并且参数范围是子类范围小于父类中的范围,不符合里氏替换原则。
例子二:
public class Father { public Collection doSomething(HashMap map){ System.out.println("父类被执行..."); return map.values(); } } class Son extends Father { //放大输入参数类型 public Collection doSomething(Map map){ System.out.println("子类被执行..."); return map.values(); } }
以上是当子类的参数范围大于父类的参数范围时情况
public class Client { public static void main(String[] args) { //父类存在的地方,子类就应该能够存在 Father f = new Father(); //Son f =new Son(); HashMap map = new HashMap(); f.doSomething(map); } }
这个是主程序入口,我们运行结果看一下: 父类被执行...
当我们根据里氏替换原则用子类的对象替换父类的对象再看一下结果
public class Client { public static void main(String[] args) { //父类存在的地方,子类就应该能够存在 Son f =new Son(); HashMap map = new HashMap(); f.doSomething(map); } }
这个是主程序入口,我们运行结果看一下: 父类被执行...
我们可以看出以上的程序利用里氏替换原则对于程序来说没有带来任何变化
因此我们可以得出结论:子类中重载父类的方法,并且参数范围是子类范围大于父类中的范围时,符合里氏替换原则。
四、里氏替换原则的总结
优点:
1、我们不必关注实例化的是子类还是父类,因为无论实例化的谁对程序结果没有任何影响。
2、就是深度规范化继承,让其更适应以后的扩展
缺点:
1、因为对于继承做了一些限制,可能会对继承的一些特点进行“封杀”,会一定程度上降低程序的灵活性。
相关推荐
详细介绍了设计模式六大原则,配有示例代码和图片,有开闭原则,单一职责原则,里氏替换原则,依赖倒置原则,接口隔离原则,迪米特法则等等。
php 设计模式六大原则 单一职责原则 里氏替换原则 依赖倒置原则 接口隔离原则 迪米特法则 开闭原则 word版
设计模式六大原则(1):...设计模式六大原则(2):里氏替换原则 设计模式六大原则(3):依赖倒置原则 设计模式六大原则(4):接口隔离原则 设计模式六大原则(5):迪米特法则 设计模式六大原则(6):开闭原则
设计模式六大原则(1):...设计模式六大原则(2):里氏替换原则 设计模式六大原则(3):依赖倒置原则 设计模式六大原则(4):接口隔离原则 设计模式六大原则(5):迪米特法则 设计模式六大原则(6):开闭原则
里氏替换原则告诉我们不要破坏继承体系;依赖倒置原则告诉我们要面向接口编程;接口隔离原则告诉我们在设计接口的时候要精简单一;迪米特法则告诉我们要降低耦合。而开闭原则是总纲,他告诉我们要对扩展开放,对修改...
里氏替换原则(Liskov Substitution Principle,LSP):子类应该能够替换掉父类并且工作正常,即子类必须能够完全替代父类的功能而不产生错误。这个原则保证了代码的可靠性和稳定性。 接口隔离原则(Interface ...
详细介绍设计模式的六大原则,有不足之处希望大家多指教。参考《设计模式之禅》
2、里氏替换原则(Liskov Substitution Principle,LSP) 3、依赖倒置原则(Dependence Inversion Principle,DIP) 4、接口隔离原则(Interface Separate Principle,ISP) 5、合成/聚合复用原则(Composite/...
设计模式六大原则:单一职责模式、开闭原则、接口隔离原则、里氏替换原则、依赖倒置原则、迪米特法则
策略模式[STRATEGY PATTERN] 代理模式[PROXY PATTERN] 单例模式[SINGLETON PATTERN] 多例模式[MULTITION PATTERN] ...六大设计原则:单一职责原则,里氏替换原则,依赖倒置原则,接口隔离原则,迪米特法则,开闭原则。
1. 单一职责原则 2. 依赖倒置原则 3. 迪米特法则 4. 开放-封闭原则 5. 里氏替换原则(了解) 6. 接口隔离原则(了解)
本文档非常详细的介绍了程序设计六大原则的定义,问题由来,解决方案及代码样例。
这六种原则分别为单一职责原则、接口隔离原则、里氏替换原则、迪米特法则、依赖倒置原则、开闭原则。 单一职责原则 单一职责原则(SRP:Single responsibility principle),规定一个类中应该只有一个原因引起类的...
主要讲解面向对象的六大原则、主流的设计模式以及MVC和MVP模式。主要内容为:优化代码的首步、开闭原则、里氏替换原则、依赖倒置原则、接口隔离原则、迪米特原则、单例模式、Builder模式、原型模式、工厂方法模式、...
二、设计模式的六大原则 1、开闭原则(Open Close Principle) 开闭原则就是说对扩展开放,对修改关闭。在程序需要进行拓展的时候,不能去修改原有的代码,实现一个热插拔的效果。所以一句话概括就是:为了使程序...
里氏替换原则(Liskov Substitution Principle,LSP) 只要父类出现的地方都可以用子类替换。 依赖倒置原则(Dependece Inversion Principle,DIP) 面向接口编程。细节应该依赖抽象。 依赖可以传递。 依赖有三...
本书专门介绍Android源代码的设计模式,主要讲解面向对象的六大原则、主流的设计模式以及MVC和MVP模式。本书的主要内容为:优化代码的第 一步、开闭原则、里氏替换原则、依赖倒置原则、接口隔离原则、迪米特原则、...
本书专门介绍Android源代码的设计模式,主要讲解面向对象的六大原则、主流的设计模式以及MVC和MVP模式。本书的主要内容为:优化代码的第一步、开闭原则、里氏替换原则、依赖倒置原则、接口隔离原则、迪米特原则、...