这是在采访中问我的。
我回答他说,对于相同的输入集,父母和孩子都应产生相同的输出集。如果孩子想扩展父母的功能,则只能对父母支持的范围以外的新输入进行操作。这样,孩子将维持其父母签订的合同。
我举了一个例子,一个api可能正在使用这样的父母
if(parent.getOutput(10) == 5){/*do something */}
如果孩子在此处产生了不同的输出,则表明该孩子违反了其父母的合同。
他对我的回答不满意,并告诉我这很简单,并不违反LSP。 所以,我只想确认一下,如果我理解正确的话。
答案 0 :(得分:8)
不,这是不正确的。
《里斯科夫换人原则》的要点是,根据相关合同,子类应该能够与父类以相同的方式使用。对于相同的输入,不需要产生相同的输出。
在不可避免的动物主题中,下面是一个示例,其中方法为相同的输入返回不同的输出:
class Dog {
String getNoise() {
return "WOOF WOOF!!!"
}
}
class FrenchBulldog extends Dog {
String getNoise() {
return "mrfff!"
}
}
FrenchBulldog
可以在任何上下文中代表任何Dog
,并且行为相同,因此不违反LSP。
如果您改为创建类似这样的内容:
class Hotdog extends Dog implements Edible {
String getNoise() {
throw new NotImplementedException("I am actually a sausage");
}
String eat() {
return "Delicious";
}
}
然后它将不再代表Dog
。与Dog
和FrenchBulldog
完美搭配的代码不再具有应有的功能。任何狗美容师或狗窝都知道该做什么,而不管狗发出的噪音如何,但是如果您带上热狗会很困惑。这 违反了LSP。