里氏代换原则(Liskov Substitution Principle)
里氏代换原则是由麻省理工学院(MIT)计算机科学实验室的Liskov女士,在1987年的OOPSLA大会上发表的一篇文章《Data Abstraction and Hierarchy》里面提出来的,主要阐述了有关继承的一些原则,也就是什么时候应该使用继承,什么时候不应该使用继承,以及其中的蕴涵的原理。 2002年,软件工程大师Robert C. Martin,出版了一本《Agile Software Development Principles Patterns and Practices》,在文中他把里氏代换原则最终简化为一句话:"Subtypes must be substitutable for their base types",也就是说,子类必须能够替换成它们的基类。
我们把里氏代换原则解释得更完整一些:在一个软件系统中,子类应该可以替换任何基类能够出现的地方,并且经过替换以后,代码还能正常工作。子类也能够在基类的基础上增加新的行为。
里氏代换原则是对开闭原则的补充,它讲的是基类和子类的关系。只有当这种关系存在时,里氏代换关系才存在。
"正方形是长方形"是一个理解里氏代换原则的最经典的例子。在数学领域里,正方形毫无疑问是长方形,它是一个长宽相等的长方形。所以,应该让正方形继承自长方形。
长方形类如程序10-1所示。
程序10-1 长方形类Rectangle.java
1. package principle.liskovsubstitution;
2.
3. public class Rectangle {
4. private int height;
5. private int width;
6.
7. public int getHeight() {
8. return height;
9. }
10.
11. public void setHeight(int height) {
12. this.height = height;
13. }
14.
15. public int getWidth() {
16. return width;
17. }
18.
19. public void setWidth(int width) {
20. this.width = width;
21. }
22. }
继承了长方形的正方形类如程序10-2所示。
程序10-2 正方形类Square.java
1. package principle.liskovsubstitution;
2.
3. public class Square extends Rectangle {
4. public void setWidth(int width) {
5. super.setWidth(width);
6. super.setHeight(width);
7. }
8. public void setHeight(int height) {
9. super.setWidth(height);
10. super.setHeight(height);
11. }
12. }
由于正方形的长度和宽度必须相等,所以在方法setLength()和setWidth()中,对长度和宽度赋值相同。程序10-3所示的测试类中的函数zoom()用来增加长方形的长和宽。
程序10-3 测试类TestRectangle.java
1. package principle.liskovsubstitution;
2.
3. public class TestRectangle {
4. public void zoom(Rectangle rectangle, int width, int height) {
5. rectangle.setWidth(rectangle.getWidth() + width);
6. rectangle.setHeight(rectangle.getHeight() + height);
7. }
8. }
显然,当增加的长度和宽度不同时,不能够将其中的长方形换成其子类正方形。这就违反了里氏代换原则。
为了符合里氏代换原则,我们可以为长方形和正方形创建一个父类Base,并在其中定义好共有的属性,并定义一个zoom()抽象函数,如程序10-4所示。
程序10-4 父类Base.java
1. package principle.liskovsubstitution;
2.
3. public abstract class Base {
4. private int height;
5. private int width;
6.
7. public int getHeight() {
8. return height;
9. }
10.
11. public void setHeight(int height) {
12. this.height = height;
13. }
14.
15. public int getWidth() {
16. return width;
17. }
18.
19. public void setWidth(int width) {
20. this.width = width;
21. }
22.
23. public abstract void zoom(int width, int height);
24. }
长方形类继承自该父类,并编写自己的zoom()实现函数,如程序10-5所示。
程序10-5 修改后的长方形类BaseRectangle.java
1. package principle.liskovsubstitution;
2.
3. public class BaseRectangle extends Base {
4. public void zoom(int width, int height) {
5. setWidth(getWidth() + width);
6. setHeight(getHeight() + height);
7. }
8. }
正方形类也继承自该父类,并编写自己的zoom()实现函数,如程序10-6所示。
程序10-6 修改后的正方形类BaseSquare.java
1. package principle.liskovsubstitution;
2.
3. public class BaseSquare extends Base {
4. public void setWidth(int width) {
5. super.setWidth(width);
6. super.setHeight(width);
7. }
8. public void setHeight(int height) {
9. super.setWidth(height);
10. super.setHeight(height);
11. }
12.
13. public void zoom(int width, int height) {
14. int length = (width + height) /2;
15. setWidth(getWidth() + length);
16. setHeight(getHeight() + length);
17. }
18. }
编写测试函数如程序10-7所示。
程序10-7 修改后的测试类BastTest.java
1. package principle.liskovsubstitution;
2.
3. public class BastTest {
4. public void zoom(Base base, int width, int height) {
5. base.zoom(width, height);
6. }
7. }
此时的Base类可以被它的子类Rectangle和Square所替代,而不用改变测试代码。这就是符合里氏代换原则的编写方式。
由此可见,在进行设计的时候,我们尽量从抽象类继承,而不是从具体类继承。如果从继承等级树来看,所有叶子节点应当是具体类,而所有的树枝节点应当是抽象类或者接口。当然这只是一个一般性的指导原则,使用的时候还要具体情况具体分析。
引用链接:http://book.51cto.com/art/200912/166943.htm
分享到:
相关推荐
里氏代换原则(Liskov Substitution Principle,简称LSP)是面向对象设计的基本原则之一,由芭芭拉·里科夫(Barbara Liskov)在1988年提出。该原则规定,子类必须能够替换它们的基类,并且在软件系统中不会产生任何...
简单来说,里氏代换原则(LSP,Liskov Substitution Principle)指的是在软件工程中,任何引用基类的地方都能被其子类替代,而不会改变程序原有的行为。这意味着子类应该能够完全无缝地替换掉基类,使得系统在使用...
在面向对象设计中,三里氏代换原则(Liskov Substitution Principle,简称LSP)是一个核心的设计原则,它由芭芭拉·里科夫(Barbara Liskov)在1988年提出。这个原则是类型继承关系中的一个重要准则,旨在确保软件...
里氏代换原则(Liskov Substitution Principle) 里氏代换原则(Liskov Substitution Principle LSP)面向对象设计的基本原则之一。 里氏代换原则中说,任何基类可以出现的地方,子类一定可以出现。 LSP是继承复用的...
里氏替换原则(Liskov Substitution Principle,简称LSP)是面向对象设计的基本原则之一,它是由美国计算机科学家芭芭拉·里科夫(Barbara Liskov)提出的。这个原则强调的是在软件工程中,子类型必须能够替换它们的...
里氏代换原则(Liskov Substitution Principle LSP)面向对象设计的基本原则之一。 里氏代换原则中说,任何基类可以出现的地方,子类一定可以出现。 LSP是继承复用的基石,只有当衍生类可以替换掉基类,软件单位的功能...
里氏替换原则(Liskov Substitution Principle,简称LSP)是面向对象设计的基本原则之一,由Barbara Liskov在1988年提出。该原则指出,子类型必须能够替换它们的基类型而不影响程序的正确性。这意味着在软件系统中,...
里氏代换原则(Liskov Substitution Principle LSP)面向对象设计的基本原则之一。 里氏代换原则中说,任何基类可以出现的地方,子类一定可以出现。 LSP是继承复用的基石,只有当衍生类可以替换掉基类,软件单位的功能...
2、里氏代换原则(Liskov Substitution Principle) 里氏代换原则(Liskov Substitution Principle LSP)面向对象设计的基本原则之一。 里氏代换原则中说,任何基类(父类)可以出现的地方,子类一定可以出现。 LSP是...
2、里氏代换原则(Liskov Substitution Principle) 3、依赖倒转原则(Dependence Inversion Principle) 4、接口隔离原则(Interface Segregation Principle) 5、迪米特法则(最少知道原则)(Demeter Principle)...
2、里氏代换原则(Liskov Substitution Principle)里氏代换原则是面向对象设计的基本原则之一。 里氏代换原则中说,任何基类可以出现的地方,子类一定可以出现。LSP 是继承复用的基石,只有当派生类可以替换掉基类...
2、里氏代换原则(Liskov Substitution Principle) 只有当衍生类可以替换掉基类,软件单位的功能不受到影响时,基类才能真正被复用,而衍生类也能够在基类的基础上增加新的行为。 3、依赖倒转原则(Dependence ...
2. **里氏代换原则 (Liskov Substitution Principle, LSP)** 里氏代换原则强调子类必须能够替换掉它们的基类,并且在所有使用基类的地方都能正常工作。这意味着子类不能违背基类的契约,保证了代码的稳定性和一致...
里氏代换原则 里氏代换原则定义 里氏代换原则(Liskov Substitution Principle, LSP)指出,子类必须能够替换它们的基类,而不影响程序的正确性。这意味着子类对象可以在任何基类对象被预期出现的地方进行替换,...
3. 里氏代换原则(Liskov Substitution Principle, LSP) 里氏代换原则指出,如果一个软件实体能接受基类对象,那么它也应该能接受其子类对象,且行为不变。这意味着子类可以无痕地替换掉基类。在加密算法的例子中,...
2. 里氏代换原则(Liskov Substitution Principle,LSP) 里氏代换原则由Barbara Liskov提出,它指出子类型必须能够替换它们的基类型而不引起程序行为的改变。换句话说,如果一个软件实体使用的是父类型的引用,那么...
里氏代换原则(Liskov Substitution Principle) 依赖倒转原则(Dependency Inversion Principle) 接口隔离原则(接口隔离原则) 迪米特法则,又称最少知道原则(Demeter Principle) 合成复用原则(复合复用原则)
3. **里氏代换原则 (Liskov Substitution Principle, LSP)**: 里氏代换原则规定,子类对象应当能够替换掉父类对象,并且在所有程序中的行为保持一致。这意味着子类不应违背父类的约定,确保子类的兼容性。遵循LSP...
Design-Pattern 23种设计模式 创建型模式,共5种:单例模式、...里氏代换原则( Liskov Substitution Principle ,LSP ) 依赖倒转原则( Dependence Inversion Principle ,DIP ) 接口隔离法则(Interface Segregation Prin