里氏替换原则
一、什么是里氏替换原则
先在这里给大家说一下书本对于这一原则的定义:如果对每一个类型为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. 单一职责原则(Single Responsibility Principle) 单一职责原则是指一个类只负责一项职责。问题来源于类 T...
里氏替换原则告诉我们不要破坏继承体系;依赖倒置原则告诉我们要面向接口编程;接口隔离原则告诉我们在设计接口的时候要精简单一;迪米特法则告诉我们要降低耦合。而开闭原则是总纲,他告诉我们要对扩展开放,对修改...
里氏替换原则(Liskov Substitution Principle,LSP):子类应该能够替换掉父类并且工作正常,即子类必须能够完全替代父类的功能而不产生错误。这个原则保证了代码的可靠性和稳定性。 接口隔离原则(Interface ...
里氏替换原则规定,子类型必须能够替换掉它们的基类型,并且在任何使用基类型的地方,都可以安全地使用子类型。例如,如果你有一个动物接口,狗和猫都是它的子类,那么在任何接受动物作为参数的函数中,都可以安全...
程序设计六大原则是软件开发中不可或缺的指导方针,它们旨在提高代码的可读性、可维护性和可扩展性。这六个原则包括单一职责原则(Single Responsibility Principle, SRP)、里氏替换原则(Liskov Substitution ...
以下将详细介绍面向对象设计的六大原则:单一职责原则(Single Responsibility Principle, SRP)、开放封闭原则(Open-Closed Principle, OCP)、里氏替换原则(Liskov Substitution Principle, LSP)、依赖倒置原则...
在这篇文章中,我们将深入探讨设计模式的六大原则,这些原则是理解并有效应用设计模式的基础。 首先,我们要了解“开-闭”原则(Open-Closed Principle,OCP)。这个原则指出,一个软件实体(如类、模块或函数)...
2. 里氏替换原则(Liskov Substitution Principle, LSP): 根据LSP,子类对象应当能够在任何其基类对象被使用的地方进行替换,而不会影响程序的正确性。这意味着子类必须完全兼容父类的接口,不能增加额外的约束或...
面向对象六大原则是软件开发中面向对象编程的重要理论基础,它们分别是单一职责原则(Single Responsibility Principle, SRP)、开闭原则(Open/Closed Principle, OCP)、里氏替换原则(Liskov Substitution ...
2、里氏替换原则(Liskov Substitution Principle,LSP) 3、依赖倒置原则(Dependence Inversion Principle,DIP) 4、接口隔离原则(Interface Separate Principle,ISP) 5、合成/聚合复用原则(Composite/...
### 七大原则与六大关系详解 #### 一、开闭原则 (Open-Closed Principle, OCP) **定义:** 开闭原则是指一个软件实体应当对扩展开放,对修改关闭。这意味着在设计一个模块时,应该使其能够在不修改现有代码的基础...
### 设计模式之六大原则详解 #### 一、单一职责原则 (SRP) **定义**: 单一职责原则(SRP, Single Responsibility Principle)指出,一个类应该仅有一个引起它变化的原因,换句话说,一个类只应负责一项职责。 **...