C++中的面向对象编程(OOP)三大特性:封装、继承、多态
C++ 是支持面向对象编程的语言,其核心特性包括封装(Encapsulation)、继承(Inheritance)和多态(Polymorphism)。下面逐一详细介绍,并给出完整的可运行代码示例。
1. 封装(Encapsulation)
定义:将数据(属性)和操作数据的方法(函数)打包在一起,对外部隐藏内部实现细节,只暴露必要的接口。
好处:
- 数据保护(防止外部直接修改内部状态)
- 代码模块化
- 提高安全性与可维护性
实现方式:
- 使用
class(推荐)或struct - 访问修饰符:
public、protected、private - 通过
getter/setter控制访问
代码示例
#include<iostream>#include<string>classStudent{private:// 私有成员,外部无法直接访问std::string name;intage;doublescore;public:// 构造函数Student(conststd::string&n,inta,doubles):name(n),age(a),score(s){}// Getterstd::stringgetName()const{returnname;}intgetAge()const{returnage;}doublegetScore()const{returnscore;}// Setter(带验证)voidsetAge(inta){if(a>=0&&a<=150){age=a;}else{std::cout<<"年龄无效!\n";}}voidsetScore(doubles){if(s>=0&&s<=100){score=s;}else{std::cout<<"分数无效!\n";}}// 成员函数voiddisplay()const{std::cout<<"姓名: "<<name<<", 年龄: "<<age<<", 分数: "<<score<<std::endl;}};intmain(){Studentstu("张三",20,85.5);stu.display();stu.setAge(21);stu.setScore(92.0);std::cout<<"更新后: "<<stu.getName()<<" 的分数是 "<<stu.getScore()<<std::endl;return0;}2. 继承(Inheritance)
定义:子类(派生类)自动获得父类(基类)的成员(属性和方法),实现代码复用。
语法:
class派生类:访问修饰符 基类{...};访问修饰符:
public:基类 public/protected 成员在派生类中保持原访问级别(最常用)protected:基类 public 成员变为 protectedprivate:基类所有成员在派生类中变为 private
继承方式:单继承、多继承、虚继承(解决菱形继承问题)。
代码示例(单继承 + protected)
#include<iostream>// 基类classPerson{protected:std::string name;intage;public:Person(conststd::string&n,inta):name(n),age(a){}voidintroduce()const{std::cout<<"我是 "<<name<<", "<<age<<"岁。"<<std::endl;}};// 派生类classTeacher:publicPerson{private:std::string subject;public:Teacher(conststd::string&n,inta,conststd::string&sub):Person(n,a),subject(sub){}voidteach()const{std::cout<<name<<" 正在教授 "<<subject<<std::endl;}};intmain(){Teachert("李老师",45,"高等数学");t.introduce();// 继承自基类t.teach();return0;}3. 多态(Polymorphism)
定义:同一接口,不同实现。体现“一个名字,多种形态”。
C++ 中多态分为两类:
- 编译时多态(静态多态):函数重载、运算符重载、模板
- 运行时多态(动态多态):虚函数 + 继承 + 基类指针/引用
运行时多态核心:虚函数(virtual)
#include<iostream>// 基类classShape{public:virtualvoiddraw()const{// 虚函数std::cout<<"绘制形状"<<std::endl;}virtualdoublearea()const=0;// 纯虚函数 → 抽象类virtual~Shape()=default;// 虚析构函数(重要!)};// 派生类1classCircle:publicShape{private:doubleradius;public:Circle(doubler):radius(r){}voiddraw()constoverride{std::cout<<"绘制圆形"<<std::endl;}doublearea()constoverride{return3.14159*radius*radius;}};// 派生类2classRectangle:publicShape{private:doublewidth,height;public:Rectangle(doublew,doubleh):width(w),height(h){}voiddraw()constoverride{std::cout<<"绘制矩形"<<std::endl;}doublearea()constoverride{returnwidth*height;}};intmain(){// 基类指针指向派生类对象 → 多态Shape*shapes[2];shapes[0]=newCircle(5.0);shapes[1]=newRectangle(4.0,6.0);for(inti=0;i<2;++i){shapes[i]->draw();// 动态绑定,调用实际类型的方法std::cout<<"面积: "<<shapes[i]->area()<<std::endl<<std::endl;}// 清理deleteshapes[0];deleteshapes[1];return0;}关键点:
virtual关键字声明虚函数override(C++11)显式标记重写- 必须通过指针或引用调用才能实现运行时多态
- 基类应有虚析构函数,避免内存泄漏
总结对比
| 特性 | 主要作用 | 关键关键字/机制 | 使用场景 |
|---|---|---|---|
| 封装 | 隐藏实现细节 | private、public、getter/setter | 数据保护、接口设计 |
| 继承 | 代码复用 | :(冒号)、public继承 | “is-a” 关系 |
| 多态 | 统一接口,灵活扩展 | virtual、override | 框架设计、插件系统 |
面向对象设计原则(SOLID)中,这些特性是基础。实际开发中通常结合抽象类(含纯虚函数)和接口(纯虚函数类)来实现更灵活的设计。
如果你需要多继承、虚继承、运算符重载、模板多态或其他高级示例(如智能指针配合多态),随时告诉我,我可以继续补充!