这是对Liskov替代原理的正确理解吗

时间:2018-08-16 18:33:43

标签: java solid-principles liskov-substitution-principle

这是在采访中问我的。

我回答他说,对于相同的输入集,父母和孩子都应产生相同的输出集。如果孩子想扩展父母的功能,则只能对父母支持的范围以外的新输入进行操作。这样,孩子将维持其父母签订的合同。

我举了一个例子,一个api可能正在使用这样的父母

if(parent.getOutput(10) == 5){/*do something */}

如果孩子在此处产生了不同的输出,则表明该孩子违反了其父母的合同。

他对我的回答不满意,并告诉我这很简单,并不违反LSP。 所以,我只想确认一下,如果我理解正确的话。

1 个答案:

答案 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。与DogFrenchBulldog完美搭配的代码不再具有应有的功能。任何狗美容师或狗窝都知道该做什么,而不管狗发出的噪音如何,但是如果您带上热狗会很困惑。这 违反了LSP。