c++中子类与父类的关系_面向对象中父类的确立

本文探讨了面向对象设计中,关于C++子类与父类关系的传统认知误区,指出继承与多态的重要性,并提供正确确立父类的方法。通过实例分析,说明了如何避免将不合适的类作为父类,强调了寻找类间共有行为来确定父类的原则,以保持继承关系的清晰性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

封装、继承、多态,这是面向对象的三大特性。这三大特性中,有两个特性都与父类有着深深的关联:

  • 继承:是指子类可以获得父类的属性和方法。
  • 多态:是指父类引用可以指向父类对象,也可指向子类对象。在调用时,父类的引用可以根据引用具体指向的对象去调用。

可见,父类概念的区分在面向对象的设计中十分基础也十分重要。但实际上,大多数开发者对父类的概念有不小的认知偏差。本文我们将讨论这一点。

传统认知的误区

首先我们给出一个问题。

问题1:矩形是不是正方形的父类?

请先在心中给出这个问题的答案,然后在继续阅读本文。


接下来,我们给出矩形类Rectangle和正方形类Square中的方法(省略方法的具体实现),如下所示。

矩形类:

public class Rectangle {
    private double length;
    private double width;
    private String color;

    public Rectangle(double length, double width, String color) {}
    public void setLength(double length) {}
    public void setWidth(double width) {}
    public void setColor(String color) {}
    public double getArea() {}
    public String getColor() {}
}

正方形类:

public class Square {
    private double sideLength;
    private String color;
    
    public Square(double sideLength, String color) {}
    public void setSideLength(double sideLength) {}
    public void setColor(String color) {}
    public double getArea() {}
    public String getColor() {}
}

然后,请再次回答问题。

问题2:上述所示的矩形是不是正方形的父类?


在问题1中,我们往往认为矩形是正方形的父类,因为,在传统认知(主要是指几何学认知)中,正方形就是矩形的特殊情况,那矩形也必然应该是正方形的父类。

在问题2中,我们查看了矩形类Rectangle和正方形类Square的具体方法后,可以判断出矩形不是正方形的父类,因为后者的很多方式是前者不具备的。这时,如果我让你整理两者的继承关系,大家往往会遵循如下的思路:

  1. 以矩形类Rectangle作为父类,以正方形类Square作为子类。
  2. 找出矩形类Rectangle类中子父类共有的方法保留,其他方法则移动到一个新的类中。这个新的类是非正方形的矩形类NotSquare。
  3. 整理删除各个子类中可以继承得到的方法。

然后会得到下面的类图。

0e2c30267a23d34064f96d13ab9f2fec.png

如果这样,那很不幸。你落入了传统认知的误区。

正确的父类确立方法

在面向对象的设计中,父类包含了子类的共有行为,而子类则是在父类基础上的特殊化。在执行这个思想时,我们要摆脱传统认知带来的误导。

假设存在A、B、C、D四个类,我们寻找父类的办法是找寻它们的方法的交集。如果最终的交集恰好等于某个类,则这个类恰好是父类,如左图所示。如果最终的交集小于所有现存的类,则交集方法组成的是父类,如右图所示。

4e61b81b141a36e7ac49d34e56fd9b7f.png

这种父类确立方法摆脱了传统认知带来的误导,能够准确确立父类。这是,我们再分析问题2,便会发现应该是如下所示的类图。

046b3ec0a5afb3a45f42b0ab3c9ce929.png

这时我们会发现,矩形类Rectangle和正方形类Square是完全平级的两个子类,而不应该是将矩形类Rectangle作为父类。

不过也要注意,通过交集获取父类是一种遵循面向对象逻辑的方法,最终得到的父类可能在现实中没有对应的事物,进而带来命名上的困难。例如在这里并集区域被命名为了“可着色的区域”ColorableArea。并且,传统的父类确立方法也会面临命名困难,例如在错误的父类划分中也产生了一个难以命名的子类,被命名为了“矩形中不是正方形的部分”NotSquare。

当涉及的类逐渐增加时,这种父类确立方法的优势会更为明显。例如,矩形类、正方形类、圆形类、五边形类都放在一起,按照此方法仍然能够很快的得出各级父类。而如果受到传统认知的误导,则很有可能导致继承关系的杂乱。

最后,我是高级架构师易哥,这里是架构研究所。真心希望本文能让大家有所收获。

欢迎关注我们,我会偶尔出没分享软件架构和编程相关的干货知识。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值