里氏代换原则(LSP)
这好像是描述了继承的一种原则,确实,在实现继承的时候,我们尽量考虑一下,java编译器能够检查语法上对里氏代换原则的支持,但是并不能支持商业逻辑上的LSP。考虑一个比较著名的长方形与正方形的问题,它能帮助我们更加深刻的理解LSP原则。
???????? 通常,在数学上来看,正方形确实属于长方形的一种,依照这种思维,正方形继承于长方形也是自然不过了。但是别忘了,长方形的定义是什么?长方形的高小于等于长方形的宽,下面是针对LSP原则的一段测试代码:?????
Public void resize(Rectangle r){
While(r.getHeight() <= r.getWidth()){
r.setWidth(r.getWidth() + 1);
}
}
???????? 试试LSP原则在这段测试代码中成不成立:当传入的是一个长方形,它的意义在于增加长方形的高度直到不大于长方形的宽度为止,如果传入的是一个正方形,长方形的子类,想象一下,这段代码会出现什么样的结果,因为正方形的高永远等于长方形的宽,这个循环永远持续下去,直到栈溢出为止。
???????? 还有一个例子,java.util库中的properties继承于hashtable,但是properties是一种特殊的hashtable,它只接受String类型的key和value,而超类hashtable的key和value却能接受任何的数据类型。这意味着,LSP在它们之间并不成立,所以,这是一个反面教材,时刻提醒我们,该在什么情况下使用继承。