news 2026/8/30 14:49:01

23种设计模式精解:从入门到实战(三)封装—继承—多态

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
23种设计模式精解:从入门到实战(三)封装—继承—多态

面向对象三要素:封装、继承、多态

面向对象编程有三个核心特性,通常称为"三要素":

  • 封装:将数据和操作数据的方法绑定在一起,对外隐藏实现细节
  • 继承:子类复用父类的属性和行为,实现代码复用与层次化设计
  • 多态:同一接口在不同对象上有不同的实现,运行时动态绑定

三者的关系:封装是基础,继承是手段,多态是目的。下面分别展开。

封装

为什么需要封装

先看面向过程的写法。以牛郎织女的故事为例,每个行为都需要通过参数明确指定执行者和对象:

qianNiu("HongNiang", "XiaoHeBian"); // 红娘将牛牵到小河边 zhuangChe("HongNiang", "FangChe"); // 红娘将纺车装车 searchNiu("NiuLang"); // 牛郎寻找牛

问题很明显:函数内部需要处理各种人物和地点的判断,行为主体不明确,数据也没有保护——任何人都可以随意修改牛郎的牛。

封装的实现

封装的核心思想是将数据和操作数据的方法绑定在类中,对外只暴露必要的接口。

  • 成员变量(属性)通常设为private,保护内部状态
  • 成员函数(行为)设为public,作为对外接口
  • 外部必须通过类提供的方法访问属性,方法内部可以添加校验逻辑
#include <iostream> #include <string> using namespace std; class NiuLang { private: string m_niu; // 牛,私有保护 public: NiuLang(const string& niu) : m_niu(niu) {} void searchNiu() { cout << "牛郎寻找自己的牛" << endl; } string getNiu() { // 通过公开方法访问私有属性 return m_niu; } }; int main() { NiuLang niuLang("黄牛"); niuLang.searchNiu(); // 行为主体明确:就是牛郎在找牛 string niu = niuLang.getNiu(); return 0; }

封装的优势

  • 数据安全:牛郎的牛不能被外部随意修改,必须通过类提供的方法访问
  • 调用简单:调用者不需要关心内部实现,只需要知道接口怎么用
  • 便于维护:内部实现修改不影响外部调用,只要接口保持不变

继承

继承的概念

继承允许子类复用父类的属性和行为,同时可以添加自己特有的功能。

在 C++ 中,子类可以继承父类的publicprotected成员,但private成员无法直接访问——注意,私有成员仍然存在于子类对象的内存中,只是从语法层面不可访问

一个直观的类比:基因遗传相当于公共成员继承,生来就有;而知识技能相当于私有成员,需要后天学习获得,不能直接继承。

继承的实现

#include <iostream> using namespace std; class Person { public: void meeting() { cout << "参加社交活动" << endl; } void getMarried() { cout << "结婚仪式" << endl; } private: void secretMethod() {} // 子类无法访问 }; class NiuLang : public Person { // 公有继承 public: void searchNiu() { cout << "寻找牛" << endl; } // 子类特有方法 }; class ZhiNv : public Person { public: void spin() { cout << "操作纺车" << endl; } }; int main() { NiuLang nl; nl.meeting(); // 继承自 Person nl.getMarried(); // 继承自 Person nl.searchNiu(); // 自有方法 ZhiNv zn; zn.meeting(); // 同样继承自 Person zn.spin(); // 自有方法 return 0; }

NiuLangZhiNv都继承了Personmeeting()getMarried(),不需要重复编写,同时各自添加了特有的行为。

继承的内存布局

子类对象包含完整的父类子对象,再加上子类新增的成员:

sizeof(Person); // 父类成员占用的空间 sizeof(NiuLang); // 父类空间 + 子类新增成员空间

即使父类的私有成员在子类中不可访问,它们仍然占据内存空间。这也是为什么sizeof子类通常大于sizeof父类。

多态

多态的三要素

多态是面向对象最强大的特性,实现它需要三个条件:

  1. 存在继承关系
  2. 父类包含虚函数(用virtual关键字声明)
  3. 子类重写父类虚函数(用override标记)

多态的实现

通过父类指针或引用指向子类对象,调用虚函数时会执行子类的版本,这就是动态绑定——运行时才确定调用哪个实现。

#include <iostream> using namespace std; class Person { public: virtual void introduce() { // 虚函数 cout << "我是普通人" << endl; } }; class NiuLang : public Person { public: void introduce() override { // 重写,override 关键字可校验签名 cout << "我是牛郎" << endl; } }; class ZhiNv : public Person { public: void introduce() override { cout << "我是织女" << endl; } }; void sayHello(Person* p) { // 父类指针,可接收任意子类 p->introduce(); // 动态绑定:调用实际对象的版本 } int main() { NiuLang nl; ZhiNv zn; sayHello(&nl); // 输出:我是牛郎 sayHello(&zn); // 输出:我是织女 return 0; }

sayHello函数只依赖Person接口,不需要知道传入的是哪个子类。新增子类时,sayHello完全不需要修改——这就是多态带来的扩展性。

纯虚函数与抽象类

如果父类的虚函数没有默认实现,可以声明为纯虚函数:

virtual 返回类型 函数名() = 0; // 纯虚函数
  • 包含纯虚函数的类称为抽象类,不能实例化对象
  • 派生类必须实现纯虚函数,否则派生类也会成为抽象类

抽象类的作用是定义接口规范,强制子类实现特定行为。

override 关键字

override显式标记一个函数是重写父类虚函数,编译器会检查函数签名是否匹配。如果签名写错(比如参数类型不对),编译器会直接报错,避免因拼写错误导致多态失效。

小结

面向对象三要素各有分工:

  • 封装解决数据安全和代码组织问题,是面向对象的基础
  • 继承解决代码复用问题,是实现多态的前提
  • 多态解决扩展性问题,是面向对象的最终目的

三者结合,才能构建出可扩展、可维护、可读性好的大型软件系统。学习时建议按"封装 → 继承 → 多态"的顺序逐步深入,每学一个就写一个小例子验证。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/30 14:45:37

Codex与Claude Code低成本接入指南:终端AI编程助手安装与配置实战

最近一段时间&#xff0c;身边不少朋友在讨论 Codex 和 Claude Code。最开始我也以为这类终端 AI 编程助手只是“另一个聊天机器人”&#xff0c;直到把它们接入实际项目里改代码、跑测试、修报错&#xff0c;才发现这两个工具确实能改变日常开发节奏。 但这里有一个绕不开的问…

作者头像 李华
网站建设 2026/8/30 14:45:02

从802.11n LDPC码解析Wi-Fi性能飞跃:原理、实现与调试实战

简介&#xff1a;本资源是面向无线通信方向研究生、工程师及标准研究者的802.11n LDPC编码技术实践资料包&#xff0c;聚焦IEEE 802.11n标准中低密度奇偶校验码&#xff08;LDPC&#xff09;的核心实现与仿真验证。资源共25个文件&#xff0c;涵盖7个MATLAB脚本&#xff08;如b…

作者头像 李华
网站建设 2026/8/30 14:37:14

从零实现S-Bahn Seat Picker:GTFS数据、客流预测与站台选座算法

每天早晚高峰的柏林 S-Bahn 站台上&#xff0c;你总能看到两类人。一类低头刷手机&#xff0c;列车进站后再被人流推着随便上一节车厢&#xff1b;另一类则像“站台老手”&#xff0c;他们不排队&#xff0c;而是径直走到某个固定位置&#xff0c;车门一开就从容上车&#xff0…

作者头像 李华
网站建设 2026/8/30 14:35:37

基于mbed TLS的嵌入式设备安全连接AWS IoT Core实战指南

简介&#xff1a;本资源是一套面向嵌入式物联网开发者与高校实践教学的AWS IoT端到云全链路开发实操包&#xff0c;聚焦设备安全接入、加密通信与云平台协同等核心难点。资源涵盖LinkIt ONE开发板上的mbed TLS库移植、MQTT协议栈集成、X.509证书配置、AWS IoT策略与资源创建、密…

作者头像 李华