【问题标题】:Is this correct understanding of Liskov Substitution Principle这是对里氏替换原则的正确理解吗
【发布时间】:2018-08-16 18:33:42
【问题描述】:

这是在一次采访中问我的。

我回答他说,对于同一组输入,父母和孩子都应该产生相同的输出。如果孩子想扩展父母的功能,它应该只在父母支持的范围之外的新输入上做。这样,孩子将维持其父母签订的合同。

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

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

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

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

【问题讨论】:

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


    【解决方案1】:

    不,这是不正确的。

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

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

    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。与Dogs 和FrenchBulldogs 完美配合的代码不再按应有的方式运行。不管狗发出什么声音,任何狗美容师或狗窝都知道该怎么做,但如果你带热狗,就会很困惑。这违反了 LSP。

    【讨论】:

    • “不可避免的动物主题”+1
    • 那么著名的 LSP 违规示例与正方形和矩形的高度和宽度有关,其中在正方形上设置高度将宽度设置为相同的值?这只会导致不正确的结果,但并不意味着无法计算该形状的面积等......
    猜你喜欢
    • 2020-04-05
    • 1970-01-01
    • 2017-05-14
    • 1970-01-01
    • 2015-02-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多