里氏替换原则(LSP)
定义:在任何父类出现的地方都可以用它的子类类替换,且不影响功能。
解释说明:
其实LSP是对开闭原则的一个扩展,在OO思想中,我们知道对象是由一系列的状态和行为组成的,里氏替换原则说的就是在一个继承体系中,对象应该具有共同的外在特性,使用LSP时,如果想让我们的程序达到一个父类出现的地方都可以用它的子类来替换且不影响功能,那么这个父类也应该尽量声明出子类所需要的一些公共的方法,父类被子类替换之后,会比较顺利,那么为什么说它是对开闭原则的一个扩展呢?因为我们在开闭原则中说尽量使用接口和抽象类,当然这个抽象类和接口也应该尽量定义得完整,这样我们这个接口和抽象类会比较稳定,这样既符合了开闭原则也满足了里氏替换原则。

错误案例1:

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace 里氏替换原则
{
/// <summary>
/// 鸟类
/// </summary>
public class Bird
{
/// <summary>
/// 吃的方法
/// </summary>
public void Eat()
{ } /// <summary>
/// 飞的方法
/// </summary>
public void Fly()
{ }
} /// <summary>
/// 定义一个企鹅类继承鸟类
/// </summary>
public class Penguin : Bird
{ } public class Test
{
public static void ShowFly(Bird bird)
{
bird.Fly();
} public static void Main()
{
ShowFly(new Penguin());
}
}
}

解释说明:

在上面的代码中,定义了一个鸟类,企鹅类继承自鸟类。鸟类里面有飞的方法,而企鹅不会飞,所以上面的代码违反了里氏替换原则。

错误案例2:

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace 里氏替换原则
{
/// <summary>
/// 定义一个父类宠物类
/// </summary>
public class Pet
{
} /// <summary>
/// 定义一个企鹅类继承自宠物类
/// </summary>
public class PenguinDemo : Pet
{
/// <summary>
/// 游泳的方法
/// </summary>
public void Swiming()
{
Console.WriteLine("可爱企鹅在游泳");
}
} /// <summary>
/// 定义一个海豚类继承自宠物类
/// </summary>
public class Dolphin : Pet
{
/// <summary>
/// 玩游戏的方法
/// </summary>
public void PlayGame()
{
Console.WriteLine("神奇泡泡打砖块");
}
} /// <summary>
/// 测试类
/// </summary>
public class Test
{
public static void ShowPlay(Pet pet)
{
if (pet is PenguinDemo)
{
//类型转换
PenguinDemo pen = (PenguinDemo)pet;
pen.Swiming();
}
if (pet is Dolphin)
{
//类型转换
Dolphin dol = (Dolphin)pet;
dol.PlayGame();
}
}
}
}

解释说明:
如果把河豚、企鹅当做宠物,我们可以定义一个宠物类,然后,让这些宠物继承这个类,我们知道每种宠物我们跟他玩耍的方式是不一样的。比如。企鹅有游泳的方法,河豚有游戏的方法,根据这个需求,我们设计一个系统,编写一个宠物类,让企鹅继承这个宠物类,在企鹅类里创建一个游泳的方法,这个方法不能放到宠物类里面,因为并不是所有宠物都会游泳。编写河豚类时,同样让他继承宠物类,在河豚类里面编写一个游戏的方法,这个时候客户端程序在使用宠物类和它的子类的时候,就需要做判断,具体是哪个子类,我们通过宠物类是无法调用具体的方法,要做一个判断和转型,如果在加一个狗类,狗类也会有一个独立的方法,要修改之前的代码(使用宠物类和它的子类的时候,要增加判断是狗类),这很明显不符合开闭原则,也不可能符合里氏替换原则,因为这里面的任何一个宠物都无法替换他的父类,因为他们的行为是不一样的,代码的可维护性和重用性很差!

代码下载链接:http://files.cnblogs.com/files/dotnet261010/OO%E8%AE%BE%E8%AE%A1%E5%8E%9F%E5%88%99.rar

面向对象设计原则三:里氏替换原则(LSP)的更多相关文章

  1. C# 实例解释面向对象编程中的里氏替换原则

    在面向对象编程中,SOLID 是五个设计原则的首字母缩写,旨在使软件设计更易于理解.灵活和可维护.这些原则是由美国软件工程师和讲师罗伯特·C·马丁(Robert Cecil Martin)提出的许多原 ...

  2. IOS设计模式的六大设计原则之里氏替换原则(LSP,Liskov Substitution Principle)

    定义 里氏替换原则的定义有两种,据说是由麻省理工的一位姓里的女士所提出,因此以其名进行命名. 定义1:如果对一个类型为T1的对象o1,都有类型为T2的对象o2,使得以T1所定义的程序P中在o1全都替换 ...

  3. 深入理解JavaScript系列(8):S.O.L.I.D五大原则之里氏替换原则LSP

    前言 本章我们要讲解的是S.O.L.I.D五大原则JavaScript语言实现的第3篇,里氏替换原则LSP(The Liskov Substitution Principle ). 英文原文:http ...

  4. Java设计原则之里氏替换原则

    里氏代换原则由2008年图灵奖得主.美国第一位计算机科学女博士Barbara Liskov教授和卡内基·梅隆大学Jeannette Wing教授于1994年提出.其严格表述如下:如果对每一个类型为S的 ...

  5. 【面向对象设计原则】之里氏替换原则(LSP)

    里氏代换原则由2008年图灵奖得主.美国第一位计算机科学女博士Barbara Liskov教授和卡内基·梅隆大学Jeannette Wing 教授于1994年提出,所以使用的是这位女博士的性命名的一个 ...

  6. 设计模式学习--面向对象的5条设计原则之Liskov替换原则--LSP

    一.LSP简介(LSP--Liskov Substitution Principle): 定义:如果对于类型S的每一个对象o1,都有一个类型T的对象o2,使对于任意用类型T定义的程序P,将o2替换为o ...

  7. S.O.L.I.D: PHP 面向对象设计的五个基准原则

    S.O.L.I.D 是首个 5 个面向对象设计 (OOD) 准则的首字母缩写,这些准则是由 Robert C. Martin 提出的,他更为人所熟知的名字是 Uncle Bob. 这些准则使得开发出易 ...

  8. [OOD]违反里氏替换原则的解决方案

    关于OOD中的里氏替换原则,大家耳熟能祥了,不再展开,可以参考设计模式的六大设计原则之里氏替换原则.这里尝试讨论常常违反的两种形式和解决方案. 违反里氏替换原则的根源是对子类及父类关系不明确.我们在设 ...

  9. 【C#设计模式】里氏替换原则

    今天,我们再来学习 SOLID 中的"L"对应的原则:里式替换原则. 里氏替换原则 里氏替换原则(Liskov Substitution Principle):派生类(子类)对象能 ...

随机推荐

  1. [Node.js] Level 6. Socket.io

    6.2 Setting Up socket.io Server-Side So far we've created an Express server. Now we want to start bu ...

  2. (剑指Offer)面试题41:和为s的两个数字

    题目: 输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得它们的和正好是s,如果有多对数字的和等于s,输出任意一对即可. 思路: 1.枚举 固定一个数字,然后依次判断数组中该数字后面的数字与 ...

  3. (剑指Offer)面试题4:替换空格

    题目: 请实现一个函数,把字符串中的每个空格替换成“%20”,例如输入“We are happy”,则输出“We%20are%20happy”. 思路: 背景: 在网络编程中,如果URL参数中含有特殊 ...

  4. STL栈的应用之表达式求值

    #include<iostream> #include<cstring> #include<cstdio> #include<stack> using ...

  5. Android中的一些小技巧

    这个是App判断是pad还是手机的代码: public boolean isTabletDevice() { TelephonyManager telephony = (TelephonyManage ...

  6. android 开源组件合集-UI篇(2013-11-07更新)

    其实也算不上合集,只是将我经常用到的部分整理一下,如果您有好东西,也可以留言补充 1.actionbar http://actionbarsherlock.com/ https://github.co ...

  7. 总结一些Android好用的开源库

    1.android-viewFlow https://github.com/pakerfeldt/android-viewflow 2. android-viewbadger https://gith ...

  8. 算法笔记_141:无向图的欧拉回路判断问题(Java)

    目录 1 问题描述 2 解决方案   1 问题描述 Problem Description 欧拉回路是指不令笔离开纸面,可画过图中每条边仅一次,且可以回到起点的一条回路.现给定一个图,问是否存在欧拉回 ...

  9. Mac安装Myeclipse2015开发环境

    1.下载Myeclipse2015 链接: http://pan.baidu.com/s/1jHe8mFk 密码: qgeb 下载下来后,在安装的时候需要自己设置下安装目标,不然在破解的时候不是太好找 ...

  10. 一些Java面试题深入分析

    一.&和&&的差别? &和&&都能够用作逻辑与的运算符.表示逻辑与(and),当运算符两边的表达式的结果都为true时.整个运算结果才为true,否则, ...