里氏替换/开闭原则

Posted liu23

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了里氏替换/开闭原则相关的知识,希望对你有一定的参考价值。

官方定义:程序中的对象应该是可以在不改变程序正确性的前提下被它的子类所替换,也就是说所有引用基类的地方必须能透明地使用其子类的对象。通俗的来说,子类可以扩展父类的功能,但不能改变父类原有的功能。

自己理解:一个实体类如果使用的是一个父类的话,那么一定适用于子类,在程序里面把父类替换成他的子类,程序的行为没有发生变化。

实例

声明两个类,Numbers类写一个加法的方法,Number写一个减法的方法,Number继承Numbers

 class Numbers
    {
        public int NumberSum(int a, int b)
        {
            return a + b;
        }
    }

    class Number : Numbers
    {
        public int Subtraction(int a, int b)
        {
            return a - b;
        }
    }

直接调用父类

 class Program
    {
        static void Main(string[] args)
        {
            Numbers n = new Numbers();
            Console.WriteLine(n.NumberSum(1,3));
        }
    }

结果等于4

里氏替换原则,父类替换成子类,不改变结果:

 class Program
    {
        static void Main(string[] args)
        {
            Number n = new Number();
            Console.WriteLine(n.NumberSum(1,3));
        }
    }

结果没有发生变化,输出为4

个人总结:里氏替换就是父类替换子类,不会不会改变原有的程序,这是学习继承就要理解的概念,子类继承了父类,子类就以父类的身份出现。

 

开闭原则:软件实体,应该扩展而不是修改。

个人理解:这个也很好理解,其实就是面向对象的思想,拿之前计算器的例子来说,如果你把所有的运算写在一个类里面,将来改需求的时候,就要去改变整个类,不灵活

实例

/// <summary>
    /// 运算类
    /// </summary>
    public class Operation
    {
        private double _numberA = 0;
        private double _numberB = 0;

        public double numberA
        {
            get { return _numberA; }
            set { _numberA = value; }
        }
        public double numberB
        {
            get { return _numberB; }
            set { _numberB = value; }
        }
        //虚方法(用于得到结果)
        public virtual double GetResult()
        {
            double result = 0;
            return result;
        }
    }

    /// <summary>
    /// 加法类
    /// </summary>
    class opearAdd: Operation
    {
        public override double GetResult()
        {
            double result = 0;
            result = numberA + numberB;
            return result;
        }
    }
   
    /// <summary>
    /// 减法类
    /// </summary>
    class opearSub : Operation
    {
        public override double GetResult()
        {
            double result = 0;
            result = numberA - numberB;
            return result;
        }
    }
    /// <summary>
    /// 乘法类
    /// </summary>
    class opearMui : Operation
    {
        public override double GetResult()
        {
            double result = 0;
            result = numberA * numberB;
            return result;
        }
    }

    /// <summary>
    /// 除法类
    /// </summary>
    class opearDiv : Operation
    {
        public override double GetResult()
        {
            double result = 0;
            if (numberB == 0)
            {
                throw new Exception("除数不能为0");
            }
            result = numberA / numberB;
            return result;
        }
    }

根据不用的运算符调用不同的实例

    /// <summary>
    /// 运算工厂
    /// </summary>
    public class OperationFactory
    {
        public static Operation creaoperation(string operate)
        {
            Operation oper = null;
            switch (operate)
            {
                case "+":
                    oper = new opearAdd();
                    break;
                case "-":
                    oper = new opearAdd();
                    break;
                case "*":
                    oper = new opearAdd();
                    break;
                case "/":
                    oper = new opearAdd();
                    break;
            }
            return oper;
        }
    }

 

开闭原则应该是面向对象的核心,遵循这个原则可以带来维护复用的很多好处。

以上是关于里氏替换/开闭原则的主要内容,如果未能解决你的问题,请参考以下文章

「设计模式」面向对象7大设计原则(开闭,单一职责,里氏替换)

面向对象原则之一 开放封闭原则(开闭原则)

面向对象设计原则

学习设计模式 - 六大基本原则之里氏替换原则

「设计模式」六大原则之三:里氏替换原则小结

「设计模式」六大原则之三:里氏替换原则小结