里氏替换原则(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;
        }
    }
}
posted @ 2016-05-12 00:12  leestar54  阅读(365)  评论(0编辑  收藏  举报