zoukankan      html  css  js  c++  java
  • 里氏代换原则<转>

    里氏代换原则(Liskov Substitution Principle LSP)面向对象设计的基本原则之一。 里氏代换原则中说,任何基类可以出现的地方,子类一定可以出现。 LSP是继承复用的基石,只有当衍生类可以替换掉基类,软件单位的功能不受到影响时,基类才能真正被复用,而衍生类也能够在基类的基础上增加新的行为。里 氏代换原则是对“开-闭”原则的补充。实现“开-闭”原则的关键步骤就是抽象化。而基类与子类的继承关系就是抽象化的具体实现,所以里氏代换原则是对实现 抽象化的具体步骤的规范。

    示例

      LSP讲的是基类和子类的关系。只有当这种关系存在时,里氏代换关系才存在。如果两个具体的类A,B之间的关系违反了LSP的设计,(假设是从B到A的继承关系)那么根据具体的情况可以在下面的两种重构方案中选择一种。   

    -----创建一个新的抽象类C,作为两个具体类的超类,将A,B的共同行为移动到C中来解决问题。   

    -----从B到A的继承关系改为委派关系。

    详细解释

      为了说明,我们先用第一种方法来看一个例子,第二种办法在另外一个原则中说明。我们就看那个著名的长方形和正方形的例子。对于长方形的类,如果它的长 宽相等,那么它就是一个正方形,因此,长方形类的对象中有一些正方形的对象。对于一个正方形的类,它的方法有个setSide和getSide,它不是长 方形的子类,和长方形也不会符合LSP。

    eg:

        //  长方形类:
    public class Rectangle
    {
    private int width;
    private int height;
    //...
    public void setWidth(int width)
    {
    this.width = width;
    }
    public void setHeight(int height)
    {
    this.height = height;
    }
    }
    //正方形类:
    public class Square
    {
    private int width;
    private int height;
    //...
    public void setWidth(int width)
    {
    this.width = width;
    this.height = width;
    }
    public void setHeight(int height)
    {
    this.setWidth(height);
    }
    }

    那么,如果让正方形当做是长方形的子类,会出现什么情况呢?

    我们让正方形从长方形继承,然后在它的内部设置width等于height,这样,只要width或者height被赋值,那么width和height会被同时赋值,这样就保证了正方形 类中,width和height总是相等的.

    现在我们假设有个客户类,其中有个方法,规则是这样的,测试传入的长方形的宽度是否大于高度,如果满足就停止 下来,否则就增加宽度的值。

    TestCase 改变边长的函数:

            public void resize(Rectangle r)
    {
    while (r.getHeight() <= r.getWidth())
    {
    r.setHeight(r.getWidth() + 1);
    }
    }

    现在我们来看,如果传入的是基类长方形,这个运行的很好。根据LSP,我们把基类替换成它的子类,结果应该也是一样的,但是因 为正方形类的width和height会同时赋值,这个方法没有结束的时候,条件总是不满足,也就是说,替换成子类后,程序的行为发生了变化,它不满足 LSP。   

    那么我们用第一种方案进行重构,我们构造一个抽象的四边形类,把长方形和正方形共同的行为放到 这个四边形类里面,让长方形和正方形都是它的子类,问题就OK了。对于长方形和正方形,取width和height是它们共同的行为,但是给width和 height赋值,两者行为不同,因此,这个抽象的四边形的类只有取值方法,没有赋值方法。上面的例子中那个方法只会适用于不同的子类,LSP也就不会被破坏。

  • 相关阅读:
    【工业控制】What is a Waveform
    【工业控制】什么是波形
    【工业控制】学习喷墨打印技术 怎么能不知道波形
    【工业控制】UV打印机喷头波形和墨水关系
    VMware-workstation-full序列码
    【Centos】Centos7.5取消自动锁屏功能
    微信公众平台开发入门教程(图文)
    微信公众平台开发(34)微相册
    微信公众平台开发(33)在线点歌/在线音乐
    微信公众平台开发(32)快递物流
  • 原文地址:https://www.cnblogs.com/haiq/p/2311848.html
Copyright © 2011-2022 走看看