首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >为什么一个类不能随意被继承?

为什么一个类不能随意被继承?

作者头像
程序视点
发布2023-09-13 12:39:56
发布2023-09-13 12:39:56
3730
举报
文章被收录于专栏:程序小小事程序小小事
今天我们来聊聊S.O.L.I.D原则中的L:Liskov Substitution Principle(LSP),里氏替换原则。

LSP 简介

如果只看上面图片中的描述,能让大部分人直接懵逼😄

我们还是来看看相对通俗点儿的定义。 里氏替换原则(Liskov Substitution Principle,LSP)可以解释为:

派生类型(子类)必须能够替换掉它们的基类型(父类)。

这个解释对于了解"继承"的小伙伴来说,显得理所当然。

但实际情况是:不是因为有了“继承”特性,里氏替换才有意义;而是因为有了里氏替换原则,才规范了“继承”特性的使用。

PS:小二哥可能表述得有点怪。不要慌,往下看!

上一篇文章中,我们提到开闭原则的最佳实践之一是抽象化。有了抽象,我们就可以基于抽象写一些具体的实现类了--这就是基类(父类)和派生类(子类)的继承关系。

好啦!问题来啦~ 请问“这个继承关系可以随便使用吗?”

从语法上来说,怎么用 extends 关键字来实现父子类关系都可以!但从业务逻辑上看,这是有很大问题的。比如下面这个例子。

LSP 反证示例

我们有个 Dog 类。

代码语言:javascript
复制
public abstract class Dog {

    void bark() {
        System.out.println("狗叫");
    }

    public abstract void work();
}

现在,我们基于 Dog 类实现牧羊犬。

代码语言:javascript
复制
public class ShepherdDog extends Dog {

    @Override
    public void work() {
        System.out.println("放羊!");
    }
}

注意看,现在我定义Cat类,并继承Dog类

代码语言:javascript
复制
public class Cat extends Dog {

    @Override
    void bark() {
        System.out.println("猫叫!");
    }

    @Override
    public void work() {
        System.out.println("抓老鼠!");
    }
}

这里,我不仅重写了 work() 方法,还重写了 bark() 方法。因为,你没法让猫叫出狗叫声。但我重写了,对于 Cat 类来说,行为上是正确的。

好了!突然有一天,隔离邻居出远门,喊你给他条 Dog 帮他看家护院。不考虑 Dog 的品种,是 Dog 就行。请问,你是给邻居 ShepherdDog 还是 Cat?

只看基类 Dog 类型来说,基于里氏替换原则,你既可以给 ShepherdDog,又可以给 Cat。但理性告诉你,你不能给 Cat。因为,你把 Cat 给邻居,邻居会觉得你在鄙视他:咋的?古有指鹿为马,今有“借狗给猫”?

小伙伴们,肯定就会说啦:Cat 和 Dog 是两种动物了,肯定不能使用继承关系啦~

这个说法是对的。但对于我们面向对象编程过程中,尤其是在“继承”关系中,我们考虑的是“替换性”。Cat 不能替换 Dog, 因此,我们不能让 Cat extends Dog

同样,网络上经典的例子:正方形不是长方形的子类,也是如此。

大多数小伙伴觉得正方形可以继承长方形,是因为把长和宽设置为一样就成正方形了。代码语法层面上很好实现。

问题在于,如果一个程序需要长方形进行面积计算时,你用正方形来替代,计算出的结果就和预期不符了。PS:大家可以上网搜一下这个例子,小二哥这里就不啰嗦啦~

总结

由之前的例子可知,我们可以里氏替换原则来规范继承关系的实现是否合理。 如果子类可以替换它的父类,那么这个继承关系就是🆗的。

另外,里氏代换原则是对“开闭原则”的补充。上一篇中,“开闭原则”的实践技巧中就是抽象化,这其实就是抽象出基类。而什么情况下能对这个基类进行具体实现呢?满足里氏代换原则,你就可以基于基类进行具体实现。

为什么里氏代换原则这么重要,小伙伴们理解了吗?

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-08-17 08:08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序视点 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • LSP 简介
  • LSP 反证示例
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档