里氏替换原则详解--七大面向对象设计原则(2)

里氏替换原则来源:

我们都知道面向对象有三大特性:封装、继承、多态。所以我们在实际开发过程中,子类在继承父类后,根据多态的特性,可能是图一时方便,经常任意重写父类的方法,那么这种方式会大大增加代码出问题的几率。比如下面场景:类C实现了某项功能F1。现在需要对功能F1作修改扩展,将功能F1扩展为F,其中F由原有的功能F1和新功能F2组成。新功能F由类C的子类C1来完成,则子类C1在完成功能F的同时,有可能会导致类C的原功能F1发生故障。这时就有人提出了里氏替换原则。里氏替换原则这项原则最早是在1988年,由麻省理工学院一位姓里的女士(Liskov)提出来的。

里氏替换原则定义:

严格的定义:如果对每一个类型为T1的对象o1,都有类型为T2的对象o2,使得以T1定义的所有程序P在所有的对象o1都换成o2时,程序P的行为没有变化,那么类型T2是类型T1的子类型。

  通俗的定义:所有引用基类的地方必须能透明地使用其子类的对象。

更通俗的定义:子类可以扩展父类的功能,但不能改变父类原有的功能。

也就是说,在面向对象设计中,如果用一个基类对象替换一个子类对象,程序不会发生错误,但是软件实体使用用一个子类对象,但是改实体不一定能使用该子类的基类对象,如果使用,程序有可能就会出问题。

例如有两个类,一个类为CLassA,另一个是CLassB类,并且CLassB类是CLassA类的子类,那么一个方法如果可以接受一个CLassA类型的基类对象base的话,如:MethodA(base),那么它必然可以接受一个CLassA类型的子类对象sub,MethodA(sub)能够正常运行。反过来的代换不成立,如一个方法MethodB接受CLassA类型的子类对象sub为参数:MethodB(sub),那么一般而言不可以有MethodB(base),除非是重载方法。

例子:沪深A股板块数据请求的里氏替换简析:

在本实例中,可以考虑增加一个新的抽象类StockBlock,而将ShangA和ShenA类作为其子类,数据请求类Quote类针对抽象客户类StockBlock编程,根据里氏代换原则,能够接受基类对象的地方必然能够接受子类对象,因此将Quote中的Request()方法的参数类型改为Code,如果需要增加新类型的客户,只需将其作为String类的子类即可。重构后的结构如图2所示:

 里氏替换使用总结:

里氏替换包括以下四层含义:

(1).子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法。

(2).子类中可以增加自己特有的方法。

(3).当子类的方法重载父类的方法时,方法的前置条件(即方法的形参)要比父类方法的输入参数更宽松。

(4).当子类的方法实现父类的抽象方法时,方法的后置条件(即方法的返回值)要比父类更严格。

时间: 2024-11-13 01:31:10

里氏替换原则详解--七大面向对象设计原则(2)的相关文章

依赖倒置原则详解--七大面向对象设计原则(3)

依赖倒置原则来源: 类A直接依赖类B,假如要将类A改为依赖类C,则必须通过修改类A的代码来达成.这种场景下,类A一般是高层模块,负责复杂的业务逻辑:类B和类C是低层模块,负责基本的原子操作:假如修改类A,会给程序带来不必要的风险. 依赖倒置原则(Dependence Inversion Principle)是程序要依赖于抽象接口,不要依赖于具体实现.简单的说就是要求对抽象进行编程,不要对实现进行编程,这样就降低了客户与实现模块间的耦合. A.高层模块不应该依赖低层模块,二者都应该依赖其抽象.抽象

接口隔离原则详解--七大面向对象设计原则(4)

 接口隔离原则的来源: 类A通过接口I依赖类B,类C通过接口I依赖类D,如果接口I对于类A和类B来说不是最小接口,则类B和类D必须去实现他们不需要的方法.因为使用多个专门的接口比使用单一的总接口要好,所以便提出了接口隔离原则. 接口隔离原则的目的: 将臃肿的接口I拆分为独立的几个接口,类A和类C分别与他们需要的接口建立依赖关系.也就是采用接口隔离原则. 接口隔离原则的两种定义:  (1) 当把"接口"理解成一个类型所提供的所有方法特征的集合的时候,这就是一种逻辑上的概念,接口的划分

单一职责原则详解--七大面向对象设计原则(1)

单一职责原则来源: 定义:单一职责就是一个类负责一项职责.就一个类而言,应该只专注于做一件事和仅有一个引起它变化的原因. 所谓职责,我们可以理解为功能,就是设计的这个类功能应该只有一个,而不是两个或更多.也可以理解为引用变化的原因,当你发现有两个变化会要求我们修改这个类,那么你就要考虑撤分这个类了.因为职责是变化的一个轴线,当需求变化时,该变化会反映类的职责的变化. 单一职责原则,很太简单.大多数开发人员,在设计软件时也会自觉的遵守这一重要原则,因为这是常识.在软件编程中,谁也不希望因为修改了一

迪米特法则详解--七大面向对象设计原则(6)

迪米特法则的来源: 迪米特法则又叫最少知道原则,最早是在1987年由美国Northeastern University的Ian Holland提出.类与类之间的关系越密切,耦合度越大,当一个类发生改变时,对另一个类的影响也越大.于是就提出了迪米特法则.通俗的来讲,就是一个类对自己依赖的类知道的越少越好.也就是说,对于被依赖的类来说,无论逻辑多么复杂,都尽量地的将逻辑封装在类的内部,对外除了提供的public方法,不对外泄漏任何信息. 迪米特法则的简单定义:     只与直接的朋友通信. 首先来解

七大面向对象设计原则

一.面向对象原则综述 七大原则总脉络图: 二.常用的面向对象设计原则包括7个,这些原则并不是孤立存在的,它们相互依赖,相互补充. . 三.以下详细分析: (一)单一职责原则(Single Responsibility Principle, SRP) 1.定义:一个对象应该只包含单一的职责,并且该职责被完整地封装在一个类中    或者:就一个类而言,应该仅有一个引起它变化的原因. 2.分析:一个类(或者大到模块,小到方法)承担的职责越多,它被复用的可能性越小,而且如果一个类承担的职责过多,就相当于

程序员七大面向对象设计原则

在没有了解到面向对象设计的7大原则前,我只是一只豆子!   但豆子终将会成长不是吗? 1.开闭原则:一个软件实体应当对扩展开放,对修改关闭.也就是说在所涉及一个模块的时候,应当使这个模块可以在不被修改的前提下被扩展,即实现在不修改源代码的情况下改变这个模块的行为. 在开闭原则的定义中,软件实体可以指一个软件模块.一个由多个类组成的局部结构或一个读库的类. 抽象化是开闭原则的关键. 是添加新代码完成方法的重构  而不是修改源代码 声明: 本文源自 2.依赖倒转原则:高层模块不应该依赖低层模块,他们

7大面向对象设计原则

面向对象设计原则 一.概述 针对软件的可维护性和可复用性,知名软件大师Robert C.Martin认为一个可维护性(Maintainability) 较低的软件设计,通常由于如下4个原因造成:过于僵硬(Rigidity) ,过于脆弱(Fragility) ,复用率低(Immobility) ,黏度过高(Viscosity) .软件工程和建模大师Peter Coad认为,一个好的系统设计应该具备如下三个性质:可扩展性(Extensibility) ,灵活性(Flexibility),可插入性(P

【OOAD】面向对象设计原则概述

软件的可维护性和可复用性 知名软件大师Robert C.Martin认为一个可维护性(Maintainability) 较低的软件设计,通常由于如下4个原因造成:? 过于僵硬(Rigidity) ? 过于脆弱(Fragility) ? 复用率低(Immobility) ? 黏度过高(Viscosity) 软件工程和建模大师Peter Coad认为,一个好的系统设计应该具备如下三个性质:? 可扩展性(Extensibility) ? 灵活性(Flexibility)? 可插入性(Pluggabil

6大设计原则详解(一)

1. 单一职责原则(SRP) (1)概念 单一职责原则的定义是:应该有且只有一个原因引起类的改变,即一个类只负责一个职责. 比如让类C负责两个不同的职责:职责P1,P2.当由于职责P1需求发生改变而需要修改类C时,有可能会导致原本运行正常的职责P2功能发生故障. (2)举例 关于用户管理的一个类按如下类图来设计: 很显然,用户的属性和行为没有分开,按照单一职责原则,应该将其重新拆封成两个接口:用户属性接口IUserBO,用户行为接口IUserBiz. 分清职责之后的代码如下: ...... IU