b2科目四模拟试题多少题驾考考爆了怎么补救
b2科目四模拟试题多少题 驾考考爆了怎么补救

里氏代换原则_接口隔离原则_java开闭原则(8)

电脑杂谈  发布时间:2016-11-24 18:01:39  来源:网络整理

public getVelocity() { return 0; };

}

好了,所有的类都设计完成,我们把类Bird提供给了其它的代码(消费者)使用。现在,消费者使用Bird类完成这样一个需求:计算鸟飞越黄河所需的时间。

对于Bird类的消费者而言,它只看到了Bird类中有fly和getVelocity两个方法,至于里面的实现细节,它不关心,而且也无需关心,于是给出了实现代码:

测试类TestBird:

class TestBird {

public calcFlyTime(Bird bird) {

try{

double riverWidth = 3000;

System.out.println(riverWidth / bird.getVelocity());

}catch(Exception err){

System.out.println('An error occured!');

}

};

}

如果我们拿一种飞鸟来测试这段代码,没有问题,结果正确,符合我们的预期,系统输出了飞鸟飞越黄河的所需要的时间;如果我们再拿鸵鸟来测试这段代码,结果代码发生了系统除零的异常,明显不符合我们的预期。

对于TestBird类而言,它只是Bird类的一个消费者,它在使用Bird类的时候,只需要根据Bird类提供的方法进行相应的使用,根本不会关心鸵鸟会不会飞这样的问题,而且也无须知道。它就是要按照“所需时间 = 黄河的宽度 /鸟的飞行速度”的规则来计算鸟飞越黄河所需要的时间。

我们得出结论:在calcFlyTime方法中,Bird类型的参数是不能被Ostrich类型的参数所代替,如果进行了替换就得不到预期结果。因此,Ostrich类和Bird类之间的继承关系违反了里氏代换原则,它们之间的继承关系不成立,鸵鸟不是鸟。

4.4 鸵鸟到底是不是鸟?

“鸵鸟到底是不是鸟”,鸵鸟是鸟也不是鸟,这个结论似乎就是个悖论。产生这种混乱有两方面的原因:

原因一:对类的继承关系的定义没有搞清楚。

我们再来看“正方形不是长方形”这个例子,正方形在设置长度和宽度这两个行为上,与长方形显然是不同的。长方形的行为:设置长方形的长度的时候,它的宽度保持不变,设置宽度的时候,长度保持不变。正方形的行为:设置正方形的长度的时候,宽度随之改变;设置宽度的时候,长度随之改变。所以,如果我们把这种行为加到基类长方形的时候,就导致了正方形无法继承这种行为。我们“强行”把正方形从长方形继承过来,就造成无法达到预期的结果。

“鸵鸟非鸟”基本上也是同样的道理。我们一讲到鸟,就认为它能飞,有的鸟确实能飞,但不是所有的鸟都能飞。问题就是出在这里。如果以“飞”的行为作为衡量“鸟”的标准的话,鸵鸟显然不是鸟;如果按照生物学的划分标准:有翅膀、有羽毛等特性作为衡量“鸟”的标准的话,鸵鸟理所当然就是鸟了。鸵鸟没有“飞”的行为,我们强行给它加上了这个行为,所以在面对“飞越黄河”的需求时,代码就会出现运行期故障。

原因二:设计要依赖于用户要求和具体环境。

继承关系要求子类要具有基类全部的行为。这里的行为是指落在需求范围内的行为。图中鸟类具有4个对外的行为,其中2个行为分别落在A和B系统需求中:

系统需求和对象关系

A需求期望鸟类提供与飞翔有关的行为,即使鸵鸟跟普通的鸟在内,鸵鸟在飞翔这一点上跟其它普通的鸟是不一致的,它没有这个能力,所以,鸵鸟类无法从鸟类派生,鸵鸟不是鸟。

B需求期望鸟类提供与羽毛有关的行为,那么鸵鸟在这一点上跟其它普通的鸟一致的。虽然它不会飞,但是这一点不在B需求范围内,所以,它具备了鸟类全部的行为特征,鸵鸟类就能够从鸟类派生,鸵鸟就是鸟。


本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-21726-8.html

相关阅读
    发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

    热点图片
    拼命载入中...