`

Java 设计模式 - 里氏置换原则

 
阅读更多

里氏置换原则(Liskov Substitution Principle),简称LSP。所有引用基类的地方必须能够透明的使用其子类对象。也就是说,只要父类出现的地方子类就能够出现,而且替换为子类不会产生任何错误或异常。

里氏置换原则(Liskov Substitution Principle),简称LSP

定义:

Functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it.

所有引用基类的地方必须能够透明的使用其子类对象。

也就是说,只要父类出现的地方子类就能够出现,而且替换为子类不会产生任何错误或异常。但是反过来,子类出现的地方,替换为父类就可能出现问题了。

这个原则是为良好的继承定义一个规范,简单的讲,有4层含义:

一、子类必须完全实现父类的方法

定义一个抽象类

  1. public abstract class ViewPoint {  
  2.     //去丽江旅游  
  3.     public abstract void where();  

下面两个类是实现这个抽象类

  1. public class Lijiang extends ViewPoint {  
  2.    
  3.     @Override 
  4.     public void where() {  
  5.         System.out.println("欢迎来到丽江...");  
  6.     }  
  7.    
  8. }  
  9.  
  10. public class Zhangjiajie extends ViewPoint {  
  11.    
  12.     @Override 
  13.     public void where() {  
  14.         System.out.println("欢迎来到张家界...");  
  15.     }  
  16.    

人物是涂涂,在里面设置类类型来传递参数。此时涂涂要去的旅游景点还是抽象的

  1. public class Tutu {  
  2.     //定义要旅游的景点  
  3.     private ViewPoint viewpoint;  
  4.     //涂涂要去的景点  
  5.     public void setViewPoint(ViewPoint viewpoint)  
  6.     {  
  7.         this.viewpoint = viewpoint;  
  8.     }  
  9.        
  10.     public void travelTo()  
  11.     {  
  12.         System.out.println("涂涂要去旅游了");  
  13.         viewpoint.where();  
  14.     }  

场景类。设置具体要去的景点

  1. public class Sence {  
  2.     public static void main(String args[])  
  3.     {  
  4.         Tutu tutu = new Tutu();  
  5.         //设置要去的旅游景点  
  6.         tutu.setViewPoint(new Lijiang());  
  7.         tutu.travelTo();  
  8.     }  

运行结果:

涂涂要去旅游了
欢迎来到丽江...

二、子类可以有自己的特性

也就是说在类的子类上,可以定义其他的方法或属性

三、覆盖或者实现父类的方法时输入参数可以被放大

父类能够存在的地方,子类就能存在,并且不会对运行结果有变动。反之则不行。

父类,say()里面的参数是HashMap类型,是Map类型的子类型。(因为子类的范围应该比父类大)

  1. import java.util.Collection;  
  2. import java.util.HashMap;  
  3.    
  4. public class Father {  
  5.     public Collection say(HashMap map)  
  6.     {  
  7.         System.out.println("父类被执行...");  
  8.         return map.values();  
  9.     }  

子类,say()里面的参数变成了Map类型,Map范围比HashMap类型大,符合LSP原则。注意这里的say不是覆写父类的say,因为参数类型不同。而是重载。

  1. import java.util.Collection;  
  2. import java.util.Map;  
  3.    
  4. /*  
  5.  * 子类继承了父类的所有属性  
  6.  */ 
  7. public class Son extends Father {  
  8.     //方法输入参数类型  
  9.     public Collection say(Map map)  
  10.     {  
  11.         System.out.println("子类被执行...");  
  12.         return map.values();  
  13.     }  

场景类

  1. import java.util.HashMap;  
  2.    
  3. public class Home {  
  4.     public static void main(String args[])  
  5.     {  
  6.         invoke();  
  7.     }  
  8.        
  9.     public static void invoke()  
  10.     {  
  11.         //父类存在的地方,子类就应该能够存在  
  12.         //Father f = new Father();  
  13.         Son s = new Son();  
  14.         HashMap map = new HashMap();  
  15.         //f.say(map);  
  16.         s.say(map);  
  17.     }  

无论是用父类还是子类调用say方法,得到的结果都是

父类被执行...

但是,如果将上面Father里的say参数改为Map,子类Son里的say参数改为HashMap,得到的结果就变成了

f.say(map)结果:父类被执行...

s.say(map)结果: 子类被执行...

这样会造成逻辑混乱。所以子类中方法的前置条件必须与父类中被覆写的前置条件相同或者更宽。

四、覆写或者实现父类的方法时输出结果可以被缩小

其实与上面的类似,也就是父类能出现的地方子类就可以出现,而且替换为子类不会产生任何错误或者异常,使用者也无需知道是父类还是子类。但是反过来就不行了,有子类出现的地方,父类未必就适应。(毕竟子类的范围要>=父类的范围)

 

原文链接:http://www.cnblogs.com/loulijun/archive/2012/03/04/2379082.html

分享到:
评论

相关推荐

    java设计模式---诙谐易懂版

    例如,代理模式(Proxy Pattern)、单例模式(Singleton Pattern)、工厂方法模式(Factory Method Pattern)、抽象工厂模式(Abstract Factory Pattern)、适配器模式(Adapter Pattern)、模板方法模式(Template ...

    设计模式6大原则:里氏置换原则

    设计模式6大原则:里氏置换原则

    JAVA设计模式-原则和23种设计模式归纳总结

    本资源首先介绍了设计模式的六大原则,包括单一责任原则、开闭原则、里氏替换原则、接口隔离原则、合成复用原则和最少知道原则。然后,资源对23种设计模式进行了分类和总结,包括创建型模式、结构型模式和行为型模式...

    OO设计原则-里氏替换原则

    ### OO设计原则——里氏替换原则详解 #### 一、引言 面向对象设计原则(Object-Oriented Design Principles)是一套指导软件开发者如何更好地设计类、接口等面向对象元素的原则集合,旨在提高代码的可复用性、可...

    Java设计模式-图解-附代码.doc

    它们帮助开发者遵循面向对象设计原则,如单一职责原则、开闭原则、里氏替换原则、依赖倒置原则和接口隔离原则,从而提高代码的可读性、可维护性和可复用性。 在实际编程中,理解并熟练应用设计模式可以使代码更加...

    JAVA设计模式-设计模式公司出品

    设计模式公司出品的《JAVA设计模式》书籍,详细介绍了多种设计模式,适合不同水平的程序员学习和使用。 首先,我们来了解什么是设计模式。设计模式是软件开发过程中遇到的某一类问题的典型解决方案。它们通常被分为...

    计算机后端-Java-图解java设计模式014 里氏替换.avi

    计算机后端-Java-图解java设计模式014 里氏替换.avi

    计算机后端-Java-图解java设计模式015 里氏替换.avi

    计算机后端-Java-图解java设计模式015 里氏替换.avi

    设计模式之里氏转换原则

    里氏转换原则是设计模式中一个重要的理论基础,它对实现这些模式起到关键的指导作用。 1. **什么是里氏转换原则:** - LSP指出,如果一个软件实体使用的是父类型的引用,那么它应该能透明地使用子类型的实例,而...

    Java设计模式-23种设计模式详解

    Java设计模式详解 Java设计模式是前辈们对代码开发经验的总结,是解决特定问题的一系列套路。它不是语法规定,而是一套用来提高代码可复用性、可维护性、可读性、稳健性以及安全性的解决方案。 设计模式的六大原则...

    java 设计模式-个人总结

    ### Java设计模式——个人总结 #### 一、概述 本文档总结了常见的Java设计模式及其应用,涵盖了十种经典的设计模式,并提供了相应的代码示例。这些设计模式旨在解决软件开发过程中遇到的一系列常见问题,帮助...

    JAVA设计模式之设计原则 ---开闭原则源码

    开闭原则是面向对象设计中的一个核心原则,它在JAVA设计模式中占据着重要的地位。这一原则由格里·贝斯提出,旨在指导开发者如何设计可维护和可扩展的软件系统。开闭原则(Open-Closed Principle,OCP)的核心思想是...

    Java设计模式-面向对象七大设计原则

    例如:随着计算机的不断发展,程序学习这门技术也越来越重要,很多人都开启了...面向对象设计原则一共有七个:开闭原则、里氏替换原则、依赖倒转原则、单一职责原则、接口隔离原则、组合/聚合复用原则、迪米特法则。

    JAVA design pattern-java设计模式

    此外,设计模式不仅限于Java,它们也适用于其他面向对象的语言,因为它们基于普遍的软件设计原则,如开闭原则(Open-Closed Principle)、里氏替换原则(Liskov Substitution Principle)、依赖倒置原则(Dependency...

    java设计模式(刘伟)

    ### Java设计模式(刘伟) #### 一、引言 在《Java设计模式》这本书中,作者刘伟全面地介绍了24种经典的设计模式,并通过丰富的案例和代码示例进行了详细的解析。本书不仅适合初学者作为入门教材,也适合有一定...

    JAVA版-设计模式解析(第二版)综合项目实战pdf文档+视频教程

    1. **设计原则**:首先,教程会介绍SOLID原则,包括单一职责原则、开放封闭原则、里氏替换原则、接口隔离原则和依赖倒置原则。这些都是设计模式的基础,有助于编写出易于维护和扩展的代码。 2. **创建型模式**:...

    Java设计模式学习.pdf

    Java设计模式是软件开发中一种被广泛采用的方式,它是一组被反复使用、多数人知晓、分类编目、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性。 根据提供的文件内容,...

    JAVA设计模式(java设计)

    通过对这些设计模式的学习和应用,开发者能够更好地理解软件设计的原则,如单一职责原则、开放封闭原则、里氏替换原则、依赖倒置原则和接口隔离原则。这有助于编写出更具弹性、易于理解和维护的代码。在实际项目中,...

    里氏替换原则Demo

    里氏替换原则(Liskov Substitution Principle,简称LSP)是面向对象设计的基本原则之一,它是由美国计算机科学家芭芭拉·里科夫(Barbara Liskov)提出的。这个原则强调的是在软件工程中,子类型必须能够替换它们的...

    java的里氏代换原则

    2. **设计模式与里氏代换原则**: - **策略模式**:策略模式鼓励定义一组算法,并将每个算法封装起来,使其可以相互替换。通过确保所有策略类都遵循相同的接口,策略模式体现了里氏代换原则。 - **合成模式**:在...

Global site tag (gtag.js) - Google Analytics