软件架构设计原则-里氏替换原则

Posted 前进道路上的程序猿

tags:

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

前言

里氏替换原则简单的理解可以是父类用到的地方可以用子类替换并且不改变逻辑,这就要求子类可以扩展父类的功能,但不能改变父类原有的功能。里氏替换原则要求
(1) 子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法,
(2) 子类可以增加自己特有的方法
(3) 当子类的方法重载父类的方法时,方法的入参要比父类方法的入参更宽松,但返回值要比父类更严格
接下来我们就用一个案例来解释

案例

在生活中,有矩形和正方形,正方形是长宽相等的矩形,所以我们新建这样两个类

public class Rectanger 
    private long height;
    private long width;
    public long getHeight() 
        return height;
    
    public void setHeight(long height) 
        this.height = height;
    
    public long getWidth() 
        return width;
    
    public void setWidth(long width) 
        this.width = width;
    

public class Square extends Rectanger
    private long length;
    public long getLength() 
        return length;
    
    public void setLength(long length) 
        this.length = length;
    
    public long getHeight() 
        return getLength();
    
    public void setHeight(long height) 
        setLength(length);
    
    public long getWidth() 
        return getLength();
    
    public void setWidth(long width) 
        setLength(length);
    

在Test里新建方法,当长方体的宽大于等于高的时候,我们让高一直自增,直到高等于宽

public static void resize(Rectanger rectangle) 
        while(rectangle.getWidth() >= rectangle.getHeight()) 
            rectangle.setHeight(rectangle.getHeight()+1);
            System.out.println("width:"+rectangle.getWidth()+",height:"+rectangle.getHeight());
        
        System.out.println("resize方法结束");
    

然后在main方法中我们用长方体来测试

public static void main(String[] args) 
        Rectanger rectanger = new Rectanger();
        rectanger.setWidth(20);
        rectanger.setHeight(10);
        resize(rectanger);
    

运行结果如下:

然后我们用正方形来测试

 public static void main(String[] args) 
        /*Rectanger rectanger = new Rectanger();
        rectanger.setWidth(20);
        rectanger.setHeight(10);
        resize(rectanger);*/

        Square square = new Square();
        square.setLength(10);
        resize(square);
    

我们测试的时候发现代码是无限循环

为什么会出现这种情况呢,这就是因为此处不复合里氏替换原则,子类Square重写了Rectangle的相应方法,改变了相应的逻辑规则

改造

接下来我们创建一个基于长方形和正方形的抽象四边接口Quadrangle

public interface Quadrangle 
    long getWidth();
    long getHeight();

然后改造Rectangle和Square实现Quadrangle接口

public class Rectanger implements Quadrangle
    private long height;
    private long width;
    public long getHeight() 
        return height;
    
    public void setHeight(long height) 
        this.height = height;
    
    public long getWidth() 
        return width;
    
    public void setWidth(long width) 
        this.width = width;
    

public class Square implements Quadrangle
    private long length;
    public long getLength() 
        return length;
    
    public void setLength(long length) 
        this.length = length;
    
    public long getHeight() 
        return getLength();
    
    public long getWidth() 
        return getLength();
    

此时Square 没有setHeight和setWidth方法
所以在测试的时候如果Square参与resize方法会在编译的时候就报错

以上是关于软件架构设计原则-里氏替换原则的主要内容,如果未能解决你的问题,请参考以下文章

手撸golang 架构设计原则 里氏替换原则

设计模式软件设计七大原则 ( 里氏替换原则 | 定义 | 定义扩展 | 引申 | 意义 | 优点 )

设计模式软件设计七大原则 ( 里氏替换原则 | 代码示例 | 类示例 | 方法入参示例 | 方法返回值示例 )

软件设计原则---里氏替换原则

设计模式的七大原则 --里氏替换原则

软件架构设计的七大原则