里氏替换原则(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;
        }
    }
}
时间: 2024-10-26 04:18:39

里氏替换原则(Liskov Substitution Principle) LSP的相关文章

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

父类能用的地方子类也一定能用. 而子类能用的地方父类不一定能用. 子类可以扩展父类的功能,但不能改变父类原有的功能

里氏替换原则 Liskov Substitution Principle

里氏替换原则的介绍: 1) 里氏替换原则(Liskov Substitution Principle)在1988年,由麻省理工学院的以为姓里的女士提出的.2) 如果对每个类型为T1的对象o1,都有类型为T2的对象o2,使得以T1定义的所有程序P在所有的对象o1都代换成o2时,程序P的行为没有发生变化,那么类型T2是类型T1的子类型.换句话说,所有引用基类的地方必须能透明地使用其子类的对象.3) 在使用继承时,遵循里氏替换原则,在子类中尽量不要重写父类的方法4) 里氏替换原则告诉我们,继承实际上让

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

以此回顾所读<设计模式之禅>与<高校程序员的45个习惯>中Liskov部分 定义: 第一种:If for each object O1 of type S there is an object O2 fo type T such that for all programs P defined in terms of T, the behavior of P is unchanged when O1 is substitueted for O2 then S is a subtype

面向对象设计原则 里氏替换原则(Liskov Substitution Principle)

里氏替换原则(Liskov Substitution Principle LSP)面向对象设计的基本原则之一. 里氏替换原则中说,任何基类可以出现的地方,子类一定可以出现. LSP是继承复用的基石,只有当衍生类可以替换掉基类,软件单位的功能不受到影响时,基类才能真正被复用,而衍生类也能够在基类的基础上增加新的行为. 如此,问题产生了:“我们如何去度量继承关系的质量?” Liskov于1987年提出了一个关于继承的原则 “Inheritance should ensure that any pro

Java 设计模式(十一) 里氏替换原则(LSP)

里氏替换原则(Liskov Substitution Principle) LSP的基本概念 定义: 所有引用基类的地方必须能透明地使用其子类的对象 只要父类能出现的地方子类就可出现,而且替换为子类也不会产生任何错误或异常,使用者可能根本就不需要知道是父类还是子类(封装造成的多态性) 规范 子类必须完全实现父类的方法 在类中调用其他类时必然要使用父类或者接口,如果子类中不支持父类中的方法,自然就违背了LSP 子类要有自己的特性 子类是在父类的基础上实现的,有自己的特性 这也就导致了LSP的单向性

面向对象五大原则_1.单一职责原则&amp;amp;2.里氏替换原则

单一职责原则:Single Responsibility Principle (SRP) 一个类.仅仅有一个引起它变化的原因.应该仅仅有一个职责.每个职责都是变化的一个轴线.假设一个类有一个以上的职责,这些职责就耦合在了一起.这会导致脆弱的设计.当一个职责发生变化时,可能会影响其他的职责.另外,多个职责耦合在一起,会影响复用性. 比如:要实现逻辑和界面的分离. T负责两个不同的职责:职责P1.职责P2.当因为职责P1需求发生改变而须要改动类T时.有可能会导致原本执行正常的职责P2功能发生问题.

day01_面向对象五大原则_1.单一职责原则&amp;2.里氏替换原则

单一职责原则:Single Responsibility Principle (SRP) 一个类,只有一个引起它变化的原因.应该只有一个职责.每一个职责都是变化的一个轴线,如果一个类有一个以上的职责,这些职责就耦合在了一起.这会导致脆弱的设计.当一个职责发生变化时,可能会影响其它的职责.另外,多个职责耦合在一起,会影响复用性.例如:要实现逻辑和界面的分离. T负责两个不同的职责:职责P1,职责P2.当由于职责P1需求发生改变而需要修改类T时,有可能会导致原本运行正常的职责P2功能发生故障.也就是

里氏替换原则:切忌按照常识实现类间的继承关系

什么是里氏替换原则 里氏替换原则(Liskov Substitution Principle LSP)定义为:任何基类可以出现的地方,子类一定可以出现. LSP是继承复用的基石,只有当衍生类可以替换掉基类,软件单位的功能不受到影响时,基类才能真正被复用,而衍生类也能够在基类的基础上增加新的行为. 为什么需要里氏替换原则 里氏替换原则看起来好像没啥了不起的,不就是继承要注意的一丢丢细节么,年轻人呐,你这样的思想很危险啊.事实上里氏替换原则常常会被违反,我在下面举例说明吧: 我们定义了一个矩形类:

里氏替换原则(Liskov Substitution Principle)

开放封闭原则(Open Closed Principle)是构建可维护性和可重用性代码的基础.它强调设计良好的代码可以不通过修改而扩展,新的功能通过添加新的代码来实现,而不需要更改已有的可工作的代码.抽象(Abstraction)和多态(Polymorphism)是实现这一原则的主要机制,而继承(Inheritance)则是实现抽象和多态的主要方法. 那么是什么设计规则在保证对继承的使用呢?优秀的继承层级设计都有哪些特征呢?是什么在诱使我们构建了不符合开放封闭原则的层级结构呢?这些就是本篇文章将

设计模式六大原则(2):里氏替换原则

里氏替换原则 肯定有不少人跟我刚看到这项原则的时候一样,对这个原则的名字充满疑惑.其实原因就是这项原则最早是在1988年,由麻省理工学院的一位姓里的女士(Barbara Liskov)提出来的. 定义1:如果对每一个类型为 T1的对象 o1,都有类型为 T2 的对象o2,使得以 T1定义的所有程序 P 在所有的对象 o1 都代换成 o2 时,程序 P 的行为没有发生变化,那么类型 T2 是类型 T1 的子类型. 定义2:所有引用基类的地方必须能透明地使用其子类的对象. 问题由来:有一功能P1,由