• 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鸟类,虽然现实中企鹅也是鸟,但在代码中却不行。

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

      

  • 相关阅读:
    deep learning 以及deep learning 常用模型和方法
    神经网络和误差逆传播算法(BP)
    机器学习常见面试题整理
    Xcode8更新CocoaPods报错解决办法
    iOS、swift、React Native学习常用的社区、论坛
    iOS 一个app跳转另一个app并实现通信(如A跳到B并打开B中指定页面)
    Xcode LLDB Debug教程
    BLOCK封装带菊花的网络请求
    AFN的初步封装(post、GET、有无参数)
    银行卡格式化输出及后四位显示
  • 原文地址:https://www.cnblogs.com/shadoll/p/14201608.html
Copyright © 2020-2023  润新知