• 里氏替换原则(Liskov Substitution Principle) LSP


    using System;
    using System.Collections.Generic;
    using System.Text;
    
    namespace LiskovSubstitutionPrinciple
    {
        //里氏替换原则(Liskov Substitution Principle) LSP
        //If for each object o1 of type S there is an object o2 of type T such that for all programs P defined in terms of T,
        //the behavior of P is unchanged when o1 is substituted for o2 than S is a subtype of T.
        //(如果对每一个类型为S的对象o1,都有类型为T的对象o2,使得以T定义的所有程序P在所有对象o1都替换成o2时,程序P的行为没有发生变化,那么类型S是类型T的子类型。)
        //通俗点讲,只要父类能出现的地方子类就可以出现,而且替换为子类也不会产生任何错误或异常,使用者根本不需要知道是父类还是子类。
        //但是反过来就不行了,有子类出现的地方,父类未必能适应(因为子类可能存在自己的方法属性,父类并不知道呀)。
        class Program
        {
            static void Main(string[] args)
            {
                Square square = new Square(50);
                //隐式转换,只要父类Shape能出现的地方子类就可以出现
                Shape shape = new Rectangle(30, 80);//替换为子类也不会产生任何错误或异常,这是因为子类肯定继承了父类的方法属性。
                //显示转换
                Shape shape2 = (Shape)square;
    
                //只要父类Shape能出现的地方子类square、rectangle就可以出现
                GetShapeArea(shape);
                GetShapeArea(shape2);
                GetShapeArea(square);
    
                //只要父类IDisposable能出现的地方子类square、rectangle就可以出现
                DisposeShape(shape);
                DisposeShape(shape2);
                DisposeShape(square);
            }
    
            static public void GetShapeArea(Shape shape)
            {
                //得益于LSP,我们不用知道实际的子类是什么,提高了扩展性
                Console.WriteLine(shape.Name + "的面积为" + shape.GetArea());
            }
    
            //同理,继承接口也是一种继承,暂且认为接口IDisposable也是父类吧~
            static public void DisposeShape(IDisposable obj)
            {
                obj.Dispose();
            }
        }
    
        /// <summary>
        /// 有抽象方法的类一定是抽象类,抽象类自身不能被实例化。
        /// 继承增强了耦合,父类在进行改动时,要考虑子类的修改,不然全部子类都要重构!
        /// </summary>
        public abstract class Shape : IDisposable
        {
            private string name;
    
            public string Name
            {
                get { return name; }
                set { name = value; }
            }
            private int width;
    
            public int Width
            {
                get { return width; }
                set { width = value; }
            }
            private int height;
    
            public int Height
            {
                get { return height; }
                set { height = value; }
            }
    
            //子类一定要实现抽象方法
            public abstract int GetArea();
    
            public void Dispose()
            {
                Console.WriteLine(Name + "释放掉了");
            }
        }
    
        /// <summary>
        /// 正方形,继承Shape使得我们代码重用,减少工作量。
        /// </summary>
        public class Square : Shape
        {
            public Square(int width)
            {
                Name = "Square";
                Width = width;
                //继承虽好,但是只要继承,就必须拥有父类的所有属性和方法,这里的Height对于正方形来说其实没有存在的必要,因为四边都相等呐。
                Height = width;
            }
    
            //我们只需实现抽象方法,其他东西一律继承!~
            public override int GetArea()
            {
                return Width * Height;
            }
        }
    
        /// <summary>
        /// 长方形
        /// </summary>
        public class Rectangle : Shape
        {
            public Rectangle(int width, int height)
            {
                Name = "Rectangle";
                Width = width;
                Height = height;
            }
    
            public override int GetArea()
            {
                return Width * Height;
            }
        }
    }
  • 相关阅读:
    flask-scripts
    mysql相关
    day9:函数
    day8:文件操作
    day7:set和深浅copy
    day6:前两小节补充
    day5:字典dict
    day4:数据结构list
    piano class 13
    day3:数据类型 str
  • 原文地址:https://www.cnblogs.com/leestar54/p/5484138.html
Copyright © 2020-2023  润新知