第十二课 面向对象
面向对象是软件工程的常用方法,它利于项目维护、分工协作等等。面向对象通过类、对象等高级抽象来描述现实世界的问题。
面向对象三大特性:封装、继承、多态
一、封装
- 把数据和操作封装进类
- 隐藏内部细节,对外提供接口
- 保护数据安全
类的定义
#include <iostream>
#include <string>
using namespace std;
// 定义类
class Student {
private: // 私有成员:类外部不能直接访问
string name;
int age;
double score;
public: // 公有成员:外部可以直接访问
// 成员函数(方法)
void setInfo(string n, int a, double s) {
name = n;
age = a;
score = s;
}
void show() {
cout << "姓名:" << name << endl;
cout << "年龄:" << age << endl;
cout << "成绩:" << score << endl;
}
// 获取私有成员的值(getter)
string getName() {
return name;
}
int getAge() {
return age;
}
};
int main() {
// 创建对象
Student s1;
// 通过公有方法访问私有成员
s1.setInfo("Tom", 18, 90.5);
s1.show();
// s1.name = "Tom"; // 错误:name是私有成员,不能直接访问
cout << s1.getName() << endl; // Tom
return 0;
}
构造函数和析构函数
#include <iostream>
#include <string>
using namespace std;
class Student {
private:
string name;
int age;
public:
// 构造函数:对象创建时自动调用
Student() {
cout << "构造函数调用" << endl;
name = "未知";
age = 0;
}
// 有参构造函数
Student(string n, int a) {
cout << "有参构造函数调用" << endl;
name = n;
age = a;
}
// 析构函数:对象销毁时自动调用
~Student() {
cout << "析构函数调用:" << name << endl;
}
void show() {
cout << name << " " << age << endl;
}
};
int main() {
Student s1; // 调用无参构造函数
Student s2("Tom", 18); // 调用有参构造函数
s1.show();
s2.show();
return 0;
// 程序结束前会调用析构函数
}
二、继承
- 子类继承父类的特性
- 代码复用
- 建立类与类之间的关系
继承示例
#include <iostream>
#include <string>
using namespace std;
// 父类(基类)
class Person {
public:
string name;
int age;
void show() {
cout << "姓名:" << name << ",年龄:" << age << endl;
}
};
// 子类(派生类)
class Student : public Person {
public:
int score; // 新增成员
void showScore() {
cout << name << "的成绩:" << score << endl;
}
};
int main() {
Student s;
s.name = "Tom"; // 继承自父类的成员
s.age = 18; // 继承自父类的成员
s.score = 90; // 子类自己的成员
s.show(); // 调用继承的方法
s.showScore(); // 调用子类的方法
return 0;
}
继承的构造函数和析构函数
#include <iostream>
using namespace cout = std::cout;
using namespace std;
class Person {
public:
Person() {
cout << "Person构造函数" << endl;
}
~Person() {
cout << "Person析构函数" << endl;
}
};
class Student : public Person {
public:
Student() {
cout << "Student构造函数" << endl;
}
~Student() {
cout << "Student析构函数" << endl;
}
};
int main() {
Student s;
// 输出:
// Person构造函数
// Student构造函数
return 0;
// 输出:
// Student析构函数
// Person析构函数
}
三、多态
- 同一接口,不同实现
- 父类指针指向子类对象
- 使用virtual实现
多态示例
#include <iostream>
#include <string>
using namespace std;
// 父类
class Animal {
public:
// 虚函数:允许子类重写
virtual void speak() {
cout << "动物叫声" << endl;
}
};
// 子类
class Dog : public Animal {
public:
// 重写父类的虚函数
void speak() override {
cout << "汪汪汪" << endl;
}
};
class Cat : public Animal {
public:
void speak() override {
cout << "喵喵喵" << endl;
}
};
int main() {
Animal *p1 = new Dog(); // 父类指针指向子类对象
Animal *p2 = new Cat();
p1->speak(); // 输出:汪汪汪(多态)
p2->speak(); // 输出:喵喵喵(多态)
delete p1;
delete p2;
return 0;
}
纯虚函数和抽象类
#include <iostream>
using namespace std;
// 抽象类:包含纯虚函数的类
class Shape {
public:
// 纯虚函数:没有实现,必须由子类重写
virtual double area() const = 0;
};
// 圆形
class Circle : public Shape {
private:
double radius;
public:
Circle(double r) : radius(r) {}
double area() const override {
return 3.14159 * radius * radius;
}
};
// 矩形
class Rectangle : public Shape {
private:
double width, height;
public:
Rectangle(double w, double h) : width(w), height(h) {}
double area() const override {
return width * height;
}
};
int main() {
Shape *shapes[2];
shapes[0] = new Circle(5);
shapes[1] = new Rectangle(4, 6);
cout << "圆形面积:" << shapes[0]->area() << endl; // 78.53975
cout << "矩形面积:" << shapes[1]->area() << endl; // 24
return 0;
}
访问控制
#include <iostream>
using namespace std;
class MyClass {
public: // 公有:类内外都能访问
int a;
protected: // 保护:类内和子类能访问
int b;
private: // 私有:只有类内能访问
int c;
};
class SubClass : public MyClass {
public:
void test() {
a = 1; // 公有:可以访问
b = 2; // 保护:子类可以访问
// c = 3; // 私有:不能访问
}
};
int main() {
MyClass obj;
obj.a = 1; // 公有:可以访问
// obj.b = 2; // 保护:不能访问
// obj.c = 3; // 私有:不能访问
return 0;
}
友元函数
#include <iostream>
using namespace std;
class MyClass {
private:
int data;
public:
MyClass(int d) : data(d) {}
// 声明友元函数:可以访问私有成员
friend void showData(MyClass &obj);
};
// 友元函数实现
void showData(MyClass &obj) {
cout << "私有数据:" << obj.data << endl;
}
int main() {
MyClass obj(100);
showData(obj); // 输出:私有数据:100
return 0;
}
静态成员
#include <iostream>
using namespace std;
class MyClass {
public:
int normalVar; // 普通成员:每个对象一份
static int staticVar; // 静态成员:所有对象共享
MyClass(int n) : normalVar(n) {
staticVar++; // 对象创建时,静态成员+1
}
static void showCount() {
// 静态函数只能访问静态成员
cout << "对象数量:" << staticVar << endl;
}
};
// 静态成员需要在类外初始化
int MyClass::staticVar = 0;
int main() {
MyClass::showCount(); // 0
MyClass obj1(10);
MyClass::showCount(); // 1
MyClass obj2(20);
MyClass::showCount(); // 2
return 0;
}
