zoukankan      html  css  js  c++  java
  • C# 设计原则-里氏替换原则

      里氏替换原则,全称Liskov Substitution Principle,英文缩写LSP。

      一个程序中如果使用的是一个父类,那么该程序一定适用于其子类,而且程序察觉不出父类和子类对象的区别。也就是说在程序中,把父类替换成它的子类,程序的行为没有任何变化。

      关于里氏替换原则的反例有不少,举个例子,企鹅不会飞。

      Birds鸟类、Sparrow麻雀类,所有的鸟类都有飞行速度。

    public abstract class Birds
    {
        //所有鸟类都应该具有飞行速度
        public abstract double FlySpeed();
    }
    
    public class Sparrow : Birds
    {
        public override double FlySpeed()
        {
            return 12;
        }
    }

      此时添加一个Penguin企鹅类,因为企鹅也是鸟类,所以继承Birds鸟类。

    public class Penguin : Birds
    {
        public override double FlySpeed()
        {
            return 0;
        }
    }

      但因为企鹅不会飞,所以飞行速度设为0,这也算是实现了FlySpeed的方法,运行结果也没问题。但如果现在有一个方法Fly用来计算一只鸟飞行300米所需要的时间。

    public static double Fly(Birds bird)
    {
        return 300 / bird.FlySpeed();
    }

      当把企鹅Penguin放进去,会出现报错,因为300/0是不合理的,这就不满足里氏替换原则。不满足该原则的原因还是因为Penguin企鹅类没有完全继承Birds鸟类,因为企鹅不能飞,实现不了FlySpeed方法。所以要解决这个问题有两种方案。

      第一种是直接在Fly方法中进行判断。

    public static double Fly(Birds bird)
    {
        //如果传入的类型为企鹅,默认返回0
        if (bird.GetType().Equals(typeof(Penguin)))
        {
            return 0;
        }
        else
        {
            return 300 / bird.FlySpeed();
        }
    }

      可这样就会违反开闭原则,以后如果需要添加新功能,得不断修改。

      第二种就是Penguin企鹅类不要继承Birds鸟类,实际上,这里Penguin企鹅就是强行继承Birds鸟类,虽然现实中企鹅也是鸟,但在代码中却不行。

      总结一下里氏替换原则的特点,就是子类可以拓展父类的功能,但是不能改变父类原有的功能。子类可以重写父类的抽象方法,但不能覆盖父类的非抽象方法。子类可以增加自己独有的方法。

      

  • 相关阅读:
    各种锁
    几百兆的sql文件无法编辑
    og4j1.x升级log4j2.x及异步日志开启
    TSNE/分析两个数据的分布
    _tkinter.TclError: no display name and no $DISPLAY environment variable
    split分割文件
    ubuntu+jdk
    进程操作
    ImportError: No module named apex
    Ubuntu 16.04.4安装Anaconda
  • 原文地址:https://www.cnblogs.com/shadoll/p/14201608.html
Copyright © 2011-2022 走看看