C++:面向对象编程(封装、继承和多态)
在C++中,面向对象编程(OOP)主要有三大特性:封装、继承和多态。下面将对这三个特性进行详细解释,并给出相应的代码示例。
1. 封装(Encapsulation)
概念
封装是将数据(属性)和操作数据的函数(方法)捆绑在一起,并对外部隐藏对象的内部实现细节,只提供一些公共的接口来与对象进行交互。这样可以提高代码的安全性和可维护性,防止外部代码直接访问和修改对象的内部数据,从而避免意外的数据损坏。
访问控制符
在C++中,使用访问控制符来实现封装,主要有三种访问控制符:
public
:公共成员,任何外部代码都可以访问。private
:私有成员,只能在类的内部访问,外部代码无法直接访问。protected
:受保护成员,只能在类的内部和派生类中访问。
代码示例
#include <iostream>
using namespace std;
class Rectangle {
private:
// 私有成员变量,外部无法直接访问
int length;
int width;
public:
// 构造函数,用于初始化对象
Rectangle(int l, int w) {
length = l;
width = w;
}
// 公共方法,用于计算矩形的面积
int area() {
return length * width;
}
// 公共方法,用于获取矩形的长度
int getLength() {
return length;
}
// 公共方法,用于设置矩形的长度
void setLength(int l) {
if (l > 0) {
length = l;
}
}
};
int main() {
Rectangle rect(5, 3);
cout << "Length: " << rect.getLength() << endl;
cout << "Area: " << rect.area() << endl;
rect.setLength(7);
cout << "New Length: " << rect.getLength() << endl;
cout << "New Area: " << rect.area() << endl;
return 0;
}
在上述代码中,length
和 width
是私有成员变量,外部代码无法直接访问。通过公共的方法 getLength()
和 setLength()
来间接访问和修改 length
的值,从而实现了数据的封装。
2. 继承(Inheritance)
概念
继承是指一个类(派生类,也称为子类)可以继承另一个类(基类,也称为父类)的属性和方法。通过继承,可以实现代码的复用,避免重复编写相同的代码。同时,派生类还可以添加自己的属性和方法,或者重写基类的方法,以满足不同的需求。
继承方式
在C++中,继承方式有三种:
public
:公共继承,基类的公共成员和受保护成员在派生类中保持原有的访问权限。private
:私有继承,基类的公共成员和受保护成员在派生类中变为私有成员。protected
:受保护继承,基类的公共成员和受保护成员在派生类中变为受保护成员。
代码示例
#include <iostream>
using namespace std;
// 基类
class Shape {
protected:
int width;
int height;
public:
Shape(int w, int h) {
width = w;
height = h;
}
// 虚函数,用于实现多态
virtual int area() {
cout << "Parent class area: ";
return 0;
}
};
// 派生类,继承自 Shape 类
class Rectangle : public Shape {
public:
Rectangle(int w, int h) : Shape(w, h) {}
// 重写基类的 area 方法
int area() {
cout << "Rectangle class area: ";
return width * height;
}
};
// 派生类,继承自 Shape 类
class Triangle : public Shape {
public:
Triangle(int w, int h) : Shape(w, h) {}
// 重写基类的 area 方法
int area() {
cout << "Triangle class area: ";
return (width * height) / 2;
}
};
int main() {
Shape *shape;
Rectangle rect(5, 3);
Triangle tri(5, 3);
// 指向 Rectangle 对象
shape = ▭
cout << shape->area() << endl;
// 指向 Triangle 对象
shape = &tri;
cout << shape->area() << endl;
return 0;
}
在上述代码中,Rectangle
和 Triangle
类都继承自 Shape
类,它们继承了 Shape
类的 width
和 height
属性以及 area()
方法。同时,Rectangle
和 Triangle
类分别重写了 area()
方法,以实现各自的面积计算逻辑。
3. 多态(Polymorphism)
概念
多态是指同一个函数调用可以根据对象的实际类型执行不同的实现。在C++中,多态主要通过虚函数和函数重载来实现。虚函数允许在基类中声明一个函数为虚函数,派生类可以重写这个虚函数,当通过基类指针或引用调用该虚函数时,会根据对象的实际类型调用相应的派生类的实现。
虚函数和纯虚函数
- 虚函数:在基类中使用
virtual
关键字声明的函数,派生类可以重写该函数。 - 纯虚函数:在基类中使用
virtual
关键字声明,并且赋值为 0 的函数,纯虚函数没有具体的实现,包含纯虚函数的类称为抽象类,抽象类不能实例化对象。
代码示例
#include <iostream>
using namespace std;
// 抽象类
class Shape {
public:
// 纯虚函数
virtual int area() = 0;
};
// 派生类,继承自 Shape 类
class Rectangle : public Shape {
private:
int width;
int height;
public:
Rectangle(int w, int h) {
width = w;
height = h;
}
// 重写基类的纯虚函数
int area() {
return width * height;
}
};
// 派生类,继承自 Shape 类
class Triangle : public Shape {
private:
int base;
int height;
public:
Triangle(int b, int h) {
base = b;
height = h;
}
// 重写基类的纯虚函数
int area() {
return (base * height) / 2;
}
};
int main() {
Shape *shape;
Rectangle rect(5, 3);
Triangle tri(5, 3);
// 指向 Rectangle 对象
shape = ▭
cout << "Rectangle area: " << shape->area() << endl;
// 指向 Triangle 对象
shape = &tri;
cout << "Triangle area: " << shape->area() << endl;
return 0;
}
在上述代码中,Shape
类是一个抽象类,包含一个纯虚函数 area()
。Rectangle
和 Triangle
类继承自 Shape
类,并分别重写了 area()
方法。通过基类指针 shape
可以根据实际指向的对象类型调用相应的 area()
方法,实现了多态。
综上所述,封装、继承和多态是C++面向对象编程的核心特性,它们相互配合,使得代码更加模块化、可复用和易于维护。