[code]package com.designphilsophy.lsp.version1;
public class SmartTest
{
/**
* 长方形的长不短的增加直到超过宽
* @param r
*/
public void resize(Rectangle r)
{
while (r.getHeight() <= r.getWidth() )
{
r.setWidth(r.getWidth() + 1);
}
}
}
在上边的代码中我们定义了一个长方形和一个继承自长方形的正方形,看着是非常符合逻辑的,但是当我们调用SmartTest类中的resize方法时,长方形是可以的,但是正方形就会一直增大,一直long溢出。但是我们按照我们的里氏替换原则,父类可以的地方,换成子类一定也可以,所以上边的这个例子是不符合里氏替换原则的。
问题由来:有一功能P1,由类A完成。现需要将功能P1进行扩展,扩展后的功能为P,其中P由原有功能P1与新功能P2组成。新功能P由类A的子类B来完成,则子类B在完成新功能P2的同时,有可能会导致原有功能P1发生故障。
解决方案:当使用继承时,遵循里氏替换原则。类B继承类A时,除添加新的方法完成新增功能P2外,尽量不要重写父类A的方法,也尽量不要重载父类A的方法。

刚才我们写的代码的结构就是上边那样的,对于这样不符合里氏替换原则原则的关系,我们在代码重构的时候一般采用下面的方法。

我们再定义一个他们共同的父类,然后让正方形和长方形都继承自这个父类。
具体的代码如下:
[code]package com.designphilsophy.lsp.version2;
/**
* 定义一个四边形类,只有get方法没有set方法
* @author xingjiarong
*
*/
public abstract class Quadrangle {
protected abstract long getWidth();
protected abstract long getHeight();
}
[code]package com.designphilsophy.lsp.version2;
/**
* 自己声明height和width
* @author xingjiarong
*
*/
public class Rectangle extends Quadrangle {
private long width;
private long height;
public void setWidth(long width) {
this.width = width;
}
public long getWidth() {
return this.width;
}
public void setHeight(long height) {
this.height = height;
}
public long getHeight() {
return this.height;
}
}
[code]package com.designphilsophy.lsp.version2;
/**
* 自己声明height和width
* @author xingjiarong
*
*/
public class Square extends Quadrangle
{
private long width;
private long height;
public void setWidth(long width) {
this.height = width;
this.width = width;
}
public long getWidth() {
return width;
}
public void setHeight(long height) {
this.height = height;
this.width = height;
}
public long getHeight() {
return height;
}
}
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-37331-2.html
为什么歌还要唱得这么好