六大设计原则-里氏替换原则

网友投稿 280 2022-11-21

六大设计原则-里氏替换原则

2.里氏替换原则(Liskov Substitution Principle)(LSP)定义: 所有引用基类的地方必须能透明的使用子类对象里氏替换原则:就是说当在程序中将一个对象替换成他的子类时,程序可以继续原有的行为,他察觉不出符类和子类的区别。但是反过来却不成立,如果一个程序使用的是一个子类的话,他不一定适用于父类。 以电脑举例:电脑有CPU,电脑就是程序实体,CPU就是它使用的基类,CPU又有子类IntelCpu。 public class Cpu { public void work(){ System.out.println("CPU在工作"); } } public class IntelCpu extends Cpu { @Override public void work() { System.out.println("英特尔CPU工作"); } } public class Computer { private Cpu cpu; public void run() { this.cpu.work(); } public Cpu getCpu() { return cpu; } public void setCpu(Cpu cpu) { this.cpu = cpu; } } 电脑依赖的是父类,此时将Cpu换成Intel类型的,电脑仍能正常工作,它察觉不到任何改变,这符合里氏替换原则。 而反过来,假设现在有一台电脑,它只能使用IntelCpu才能工作。 public class IntelCpuComputer { private IntelCpu cpu; public void run() { this.cpu.work(); } public IntelCpu getCpu() { return cpu; } public void setCpu(IntelCpu cpu) { this.cpu = cpu; } } 如果此时将IntelCpu替换成父类CPU,那么计算机就不能正常工作,因为它只有在使用IntelCpu时才能正常工作。 public static void main(String[] args) { IntelCpuComputer computer = new IntelCpuComputer(); computer.setCpu(new Cpu());//报错 } 再比如说,我们都知道在数学上正方形是特殊的长方形,那么能不能说正方形就是长方形的子类呢? 我们用代码表示一下正方形和长方形: /** * 长方形 * @author ZhaoShuai * @date Create in 2020/4/12 **/ public class Rectangle { private Integer height; private Integer width; public Integer getHeight() { return height; } public void setHeight(Integer height) { this.height = height; } public Integer getWidth() { return width; } public void setWidth(Integer width) { this.width = width; } } /** * 正方形 * @author ZhaoShuai * @date Create in 2020/4/12 **/ public class Square { private Integer side; public Integer getSide() { return side; } public void setSide(Integer side) { this.side = side; } } 我们都知道,父类是通过抽取子类的共性封装而成的,从上面代码中可以看出,长方形和正方形的结构式不同的,长方形有长和宽的属性,而正方形只有变长的属性。因此,正方形不是长方形的子类,当然也可以强行来继承长方形作为父类,但是我们不是为了继承而继承,这种为了继承而继承的情况也是不属于里氏替换原则的。 package com.xiazhi.principle.lsp; /** * @author ZhaoShuai * @date Create in 2020/4/12 **/ public class SquareExtendsRectangle extends Rectangle { private Integer side; @Override public void setHeight(Integer height) { this.setSide(height); } @Override public void setWidth(Integer width) { this.setSide(width); } @Override public Integer getHeight() { return this.getSide(); } @Override public Integer getWidth() { return this.getSide(); } public Integer getSide() { return side; } public void setSide(Integer side) { this.side = side; } } 可以看出,我们给正方形强行继承了长方形,然后我们写一个测试类: public static void main(String[] args) { System.out.println("============长方形=============="); Rectangle rectangle = new Rectangle(); rectangle.setHeight(10); rectangle.setWidth(20); print(rectangle); System.out.println("============正方形=============="); Rectangle square = new SquareExtendsRectangle(); square.setHeight(10); print(square); } private static void print(Rectangle rectangle) { System.out.println("高:"+rectangle.getHeight()); System.out.println("宽:" + rectangle.getWidth()); } 测试后我们发现好像能正常运行,此时我们再加一个方法: public static void main(String[] args) { System.out.println("============长方形=============="); Rectangle rectangle = new Rectangle(); rectangle.setHeight(10); rectangle.setWidth(20); test(rectangle); System.out.println("============正方形=============="); Rectangle square = new SquareExtendsRectangle(); square.setHeight(10); test(square); } private static void print(Rectangle rectangle) { System.out.println("高:"+rectangle.getHeight()); System.out.println("宽:" + rectangle.getWidth()); } private static void test(Rectangle rectangle) { while (rectangle.getWidth() >= rectangle.getHeight()) { rectangle.setHeight(rectangle.getHeight()+1); print(rectangle); } } 运行后可以发现, 长方形可以正常运行,而正方形却会出现死循环,因此这种是不符合里氏替换原则的。因为引用父类的地方无法使用子类对象。 在类的设计时,根据依赖倒置原则,要使用抽象类或接口,如果不能使用抽象类或者接口,那么就说明设计违背了里氏替换原则(LSP)

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:基于提高RS485接口芯片通信质量的设计
下一篇:英创信息技术SBC860模块化工控机方案简介
相关文章

 发表评论

暂时没有评论,来抢沙发吧~