“一个软件实体如果使用的是一个基类的话,一定适用于其子类,而且根本不能觉察出基类对象和子类对象的区别。”
陈述:
若对每个类型S的对象o1,都存在一个类型T的对象o2,使得在所有针对T编写的程序P中,用o1替换o2后,程序P的行为功能不变,则S是T的子类型。
通俗地讲,就是子类型能够完全替换父类型,而不会让调用父类型的客户程序从行为上有任何改变。
意义:
我们在客户程序在调用某一个类时,实际上是对该类的整个继承体系设定了一套约束,继承体系中的所有类必须遵循这一约束,即前置条件和后置条件必须保持一致。这为对象继承加上了一把严格的枷锁。显然,LSP原则对于约束继承的泛滥具有重要意义。
class Rectangle { private: long width; long height; public: void setWidth(long width) { this->width = width; } long getWidth() { return this->width; } void setHeight(long height) { this->height = height; } long getHeight() { return this->height; } }; //正方形类 class Square { private: long side; public: void setSide(long side) { this->side = side; } long getSide() { return side; } };
//正方形类(如果继承自长方形类): class Square : public Rectangle { private: long side; public: void setWidth(long width) { setSide(width); } long getWidth() { return getSide(); } void setHeight(long height) { setSide(height); } long getHeight() { return getSide(); } long getSide() { return side; } void setSide(long side) { this->side = side; } };
class SmartTest { public: void resize(Rectangle r) { while (r.getHeight() <= r.getWidth() ) { r.setWidth(r.getWidth() + 1); } } };从上面小函数可见,只想改变长方形的宽时,如果把正方形看成一种长方形的话,则正方形的长和宽都被改变了。LSP原则被破坏了,Square不应成为Rectangle的子类。
class Quadrangle { public: virtual long getWidth() = 0; virtual long getHeight() = 0; };Quadrangle类只声明两个取值方法,不声明任何的赋值方法。
class Rectangle : public Quadrangle { private: long width; long height; public: void setWidth(long width) { this->width = width; } long getWidth() { return this->width; } void setHeight(long height) { this->height = height; } long getHeight() { return this->height; } };//正方形类:
class Square : public Quadrangle { private: long side; public: void setSide(long side) { this->side = side; } long getSide() { return side; } long getWidth() { return getSide(); } long getHeight() { return getSide(); } };问题如何得以避免?
参考资源:
《设计模式:可复用面向对象软件的基础》,ERICH GAMMA RICHARD HELM RALPH JOHNSON JOHN VLISSIDES著作,李英军 马晓星 蔡敏 刘建中译,机械工业出版社,2005.6
《敏捷软件开发:原则、模式与实践》,Robert C. Martin著,邓辉译,清华大学出版社,2003.9
《设计模式解析》,Alan Shalloway等著(徐言声译),人民邮电出版社,2006.10