搜索
写经验 领红包
 > 影视

里氏替换原则优缺点(里氏替换原则阐述什么道理)

导语:趣谈设计模式之里氏替代原则

里氏替换原则源于麻省理工学院的Liskov女士在1988年提出了一个关于继承的原则。提起继承关系,一般情况大家都会说是子类和父类具有is-A关系。如何做?有哪些注意事项?带着上述疑问来学习一下里氏替换原则。

白话版的里氏替换原则释义:如果我们把代码中使用父类对象的地方用子类对象代替,代码还能正常工作。该原则也是我们的设计目标之一。实际操作过程中,需要做到子类不能修改父类既有的功能,只能进行扩展。在编码时特别需要以下几点:

一、子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法。抽象方法在C++中指的是纯虚函数,子类是必须要实现的,不然编译器也不会放过你的,报错是必然的。父类已经实现的功能,是可以覆盖的,编译器认为也是OK的。这么做违反了里氏替换原则,也是我们不提倡的。

二、子类中可以增加自己特有的方法。建立子类的初心是扩展父类的功能,这个比较好理解,无须赘述。

三、当子类的方法重载父类的方法时,方法的前置条件(即方法的输入/入参)要比父类方法的输入参数更宽松。这点没有特殊情况下不建议使用,很容易搞出问题。

四、当子类的方法实现父类的方法时(重载/重写或实现抽象方法)的后置条件(即方法的输出/返回值)要比父类更严格或相等。这一点也是不建议使用,原因同上一条。

前两条还是好理解的,后两条相对来说比较晦涩。项目经验和教训告诉大家,在类的继承时,没有特殊应用场景和绝对的把握,不要轻易挑战后两条要求。即使你对后两条应用的比较熟练,在排查问题时也会造成一定的干扰。就版本维护来说,如果其他同事不能把握的话,这些代码变成你祖传的啦,加薪升职有阻碍哟。

举个正常使用类的继承的栗子,供大家参考一下。

李小菜在编写一个动物世界的程序,在处理鲸鱼的时候碰到了难题。众所周知,鲸鱼是一种会游泳的哺乳类动物。让它继承鱼的基类,但是鱼的很多特性是鲸鱼不具备的,比如使用腮进行呼吸、卵生繁殖。让它继承哺乳类的基类,但是鲸鱼会游泳。如果强行让鲸鱼继承鱼类或者哺乳类的话,必然会违反里氏替换规则。

百思不得其解后,李小菜只好来找王大侠。王大侠费了一番周折找到了一个合适的解决方案。王大侠沉重的说:“小菜啊,这个问题是典型的继承问题,要避免继承泛滥。最好的方式是新增水生物种类,并具备游泳属性。鲸鱼类继承哺乳类和水生生物类就可以解决问题“。

问题解决之后,王大虾又给李小菜同学拔了一下高,上升到理论的高度。

如果两个具体的类A,B之间的关系违反了里氏替代原则,假设是从B到A的继承关系,那么根据具体的情况可以在下面的两种重构方案中选择一种:

一、创建一个新的抽象类C,作为两个具体类的基类,将A,B的共同行为移动到C中来解决问题。

二、从B到A的继承关系改为关联关系。

通过此问题,李小菜对王大虾的敬仰之情又加深了一步。

结语

里氏替代原则最主要的优势是可以约束继承泛滥,也是开闭原则的一种体现。在面向对象程序设计时,时刻牢记的原则之一。

免责声明:本站部份内容由优秀作者和原创用户编辑投稿,本站仅提供存储服务,不拥有所有权,不承担法律责任。若涉嫌侵权/违法的,请与我联系,一经查实立刻删除内容。本文内容由快快网络小余创作整理编辑!