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

yog*_*ogi 1 java liskov-substitution-principle solid-principles

这是在接受采访时向我询问的.

我回答他说,对于同一组输入,父母和孩子都应该产生相同的输出.如果孩子想要扩展父母的功能,它应该只对父母支持范围之外的新输入做.通过这种方式,孩子将保持其父母的合同.

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

if(parent.getOutput(10) == 5){/*do something */}
Run Code Online (Sandbox Code Playgroud)

如果孩子在这里产生了不同的输出,那么那个孩子已经违反了它的父母所做的合同.

他对我的回答并不满意,并告诉我这是简单的重写,并不违反LSP.所以,我只是想确认,如果我理解这是正确的.

tha*_*guy 13

不,这不正确.

Liskov替换原则的要点是,根据相关合同,子类应该能够以与父类相同的方式使用.对于相同的输入,它不需要产生相同的输出.

在不可避免的动物主题中,这是一个示例,其中方法为同一输入返回不同的输出:

class Dog {
  String getNoise() {
    return "WOOF WOOF!!!"
  }
}

class FrenchBulldog extends Dog {
  String getNoise() {
    return "mrfff!"
  }
}
Run Code Online (Sandbox Code Playgroud)

FrenchBulldog可以代表Dog任何上下文中的任何内容并以相同的方式运行,因此它不违反LSP.

如果你改为创建这样的东西:

class Hotdog extends Dog implements Edible {
  String getNoise() {
    throw new NotImplementedException("I am actually a sausage");
  }
  String eat() {
    return "Delicious";
  }
}
Run Code Online (Sandbox Code Playgroud)

然后它再也不能代表了Dog.与Dogs和FrenchBulldogs 完美协作的代码不再像它应该的那样运行.任何狗美容师或狗窝都知道该怎么做,不管狗的噪音如何,但如果你带一个热狗,将会非常困惑.这违反了LSP的.

  • "那不可避免的动物主题"+1 (7认同)
  • 那么著名的正方形和长方形高度和宽度违反 LSP 的例子呢,在正方形上设置高度将宽度设置为相同的值?这只会导致不正确的结果,但并不意味着无法计算该形状的面积等...... (2认同)