封装保护数据、继承扩展类型、多态统一调用:shape基类私有成员+纯虚draw(),circle/rectangle继承并重写draw(),vector多态调用,配合virtual析构、override和指针调用确保正确性。

写一个封装、继承、多态综合案例,关键不是堆砌语法,而是让三者自然协同:用封装保护数据、用继承扩展类型、用多态统一调用接口。下面以“图形绘制系统”为例,结构清晰、贴近实际,可直接运行验证。
1. 封装:定义基类并隐藏内部细节
先设计一个Shape(图形)基类,把坐标、颜色等属性设为private,只提供安全的公共接口:
- 成员变量如
x_, y_, color_全部私有; - 对外仅开放
setPos()、setColor()等带校验的 setter; - 声明纯虚函数
draw(),强制子类实现——这是多态的起点。
2. 继承:派生具体图形类并复用/扩展
从 Shape 派生 Circle 和 Rectangle:
-
Circle新增私有成员radius_,重写draw()输出圆形信息; -
Rectangle新增width_, height_,也重写draw(); - 构造函数中调用基类初始化,避免重复代码——体现继承的代码复用价值。
3. 多态:通过基类指针/引用统一调度
在主逻辑中,不关心具体类型,只操作 Shape* 或 std::vector<shape></shape>:
- 创建
Circle c(100, 50, "red", 20);和Rectangle r(200, 80, "blue", 60, 40);; - 把它们的地址存入
std::vector<shape> shapes</shape>; - 遍历调用
shape->draw()—— 运行时自动调用各自重写的版本,无需 if-else 判断类型。
4. 补充要点:确保多态生效的关键细节
很多初学者写不出正确结果,常因忽略以下三点:
- 基类析构函数必须是 virtual:否则 delete Shape* 时子类析构函数不执行;
-
重写函数要加
override关键字,编译器会检查签名是否匹配; -
调用必须通过指针或引用:直接用对象(如
Shape s = c;)会触发对象切片,丢失多态性。










