大家好,感谢邀请,今天来为大家分享一下设计原理:里氏代换原理(LSP)的问题,以及和的一些困惑,大家要是还不太明白的话,也没有关系,因为接下来将为大家分享,希望可以帮助到大家,解决大家的问题,下面就开始吧!
定义
里氏替换原则是由Barbara Liskov于1987年提出的,Liskov是她的姓氏,在中国翻译成Liskov。
LSP为语言添加了新的签名约束(关于协变和逆变,请参阅这篇文章Java中的逆变和协变):
子类型中方法参数的逆变。子类型中返回类型的协方差。子类型的方法不应引发新的异常,除非这些异常本身是超类型的方法引发的异常的子类型。从合约的角度来看,里氏替换原则有四层含义:
方法的前置条件要求不能更严格(可以更宽松) 方法的后置条件不能更宽松(可以更严格) 子类必须维护父类约定的不变性历史约束。类属性只能通过方法修改。由于子类会引入父类中不存在的方法,方法的引入可能会导致原本在父类中不可修改的属性在子类中被修改。历史的限制不允许这样做。行为。
思考
继承描述的是is-a关系,开闭原则要求我们使用继承来添加功能,LSP原则指导我们如何继承。
在我之前写的一篇关于里氏替换原理的文章中,我提到:
每个类都会有公共方法,有些类会实现接口供其他类使用,它们将处于服务位置。每个公共方法都是其自身做出的承诺。只要您按要求调用,就会提供正确的服务。继承之后,子类固然获得了超类带来的‘财富’,但更重要的是,它必须遵守超类做出的承诺。如果你违背了这个承诺,你实际上就没有资格继承超类。如果违反继承原则,则不能使用开闭原则。如果子类不按照合约设置进行编码,那就是在给用户挖坑。
实践
需求要求设计一个鸟类继承系统。以下是我们设计的抽象基类:
公共抽象类Bird { 私有字符串名称;公共无效setName(字符串名称){ this.name=name; } public void Fly() { System.out.println(name + 'fly'); }大多数鸟都在这个基类中一切正常,但是有一天一只企鹅来了。企鹅不会飞,所以我们重写了fly方法。
公共类企鹅{ @Override public void Fly() { throw new RuntimeException();由于企鹅不会飞,所以在fly方法中直接抛出异常。
注意,这里违反了LSP原则。基类没有抛出异常,用户可以正常使用。然而,Penguin 类中的Fly 方法会抛出异常,这违反了基类遵守的约定。
为了解决这个问题,我们需要应用接口分离原则来拆分Bird类。从Penguin的角度来看,飞行功能不是Bird的责任。应该单独放到一个接口中,飞鸟自己实现即可。如果像上面那样,大多数鸟都有默认的飞行实现,我们可以制作一个默认的飞行实现类,并使用组合将其放入飞鸟中。
公共抽象类Bird { 私有字符串名称;公共无效setName(字符串名称){ this.name=name; }}public interface Flyable { public void Fly();}
总结
里氏替换原则是继承需要遵循的原则。有时我们可能无意中违反了原则要求,一是因为我们没有意识到,二是因为我们设计的接口和抽象基类存在问题。当遇到违反LSP原则的继承时,有两种解决方法:1.修改实现,2.改变设计。
设计模式文章链接
设计原理:里氏替换原理(LSP)
设计原理开闭原理(OCP)
用户评论
里氏替换原则听起来好专业啊!感觉对学习面向对象编程确实有帮助,以后coding的时候会 try try see!
有20位网友表示赞同!
这篇文章讲得挺清楚的,里氏替换原则确实能让我们写出更健壮、可维护的代码。以后开发项目中要牢记这个原则!
有20位网友表示赞同!
感觉学习里氏替换原则还是蛮有挑战性的,我的实践经验还不足够深入理解它。希望能看到更多实例讲解!
有11位网友表示赞同!
读完这篇文章后我才明白为什么大家那么推崇里氏替换原则,它能够保证代码的可扩展性,真是太重要了!
有8位网友表示赞同!
我之前写代码时并没有明确地遵循里氏替换原则,现在看来确实有一些地方可以改进。下次再改代码的时候一定好好参考这个原则!
有18位网友表示赞同!
感觉里氏替换原则这个名词有点吓人,实际操作起来还挺简单的,关键是要理解子类应该继承父类的行为预期。建议文章里多加入实例代码进行说明!
有13位网友表示赞同!
这种设计原则确实能够提高代码的质量,但有时为了满足特定的需求还是要适当跳出框架,这需要开发者综合考虑实际情况。
有5位网友表示赞同!
写论文的时候学到这个概念,感觉很有用!代码和论文都一样,要保持结构清晰、逻辑一致。里氏替换原则就是很好的体现!
有12位网友表示赞同!
我觉得文章描述的里氏替换原则还是比较抽象的,建议可以加入一些具体的编程案例,这样更容易理解和应用。
有8位网友表示赞同!
对于我来说,学习里氏替换原则就像是在学习一种新的语言,需要时间和耐心去积累经验!
有17位网友表示赞同!
现在很多开源项目都遵循了里氏替换原则的设计理念,这使得代码更加模块化、可维护。值得我们学习借鉴!
有18位网友表示赞同!
这篇文章的讲解太浅层了,没有深入探讨里氏替换原则的适用场景和局限性。希望能看到更专业的分析!
有8位网友表示赞同!
我之前曾经遇到过因为不遵循里氏替换原则导致的代码复杂度爆炸的问题,现在回头看确实是一个非常重要的设计原则!
有9位网友表示赞同!
虽然里氏替换原则很有用,但在实际开发中也需要权衡成本与收益,有时为了实现特定功能可能需要做出一些妥协!
有20位网友表示赞同!
这个原則聽起來很高端啊,我目前主要还是學習基礎的程式設計概念,等以後再深入理解這種更高级的設計原則吧!
有11位网友表示赞同!
我认为里氏替换原则是一个非常重要的设计原则,它能够帮助我们写出更加清晰、高效的代码。推荐给所有软件开发人员学习!
有12位网友表示赞同!
文章写的不错!里氏替换原则确实是个很好的设计理念,可以使代码更易于维护和扩展。我以后也要好好学习一下!
有19位网友表示赞同!
对于复杂的系统来说,遵循里氏替换原则显得尤其重要,因为它能确保不同的模块之间能够协同工作,避免出现难以预料的冲突!
有20位网友表示赞同!