第8天:面向对象编程入门 - 类与对象
一、???? 今日学习目标
- ???? 掌握类与对象的定义与使用
- ???? 理解封装、继承、多态三大特性
- ???? 完成银行账户管理系统实战
- ????️ 学会构造函数与析构函数的编写
二、⚙️ 核心知识点详解
1. 类的定义与对象创建
类的基本结构
class BankAccount {
private:
string accountNumber;
double balance;
public:
// 构造函数
BankAccount(string accNo, double initialBalance)
: accountNumber(accNo), balance(initialBalance) {}
// 成员函数
void deposit(double amount) {
balance += amount;
}
bool withdraw(double amount) {
if (balance >= amount) {
balance -= amount;
return true;
}
return false;
}
double getBalance() const {
return balance;
}
};
// 创建对象
BankAccount myAccount("123456", 1000.0);
2. 封装与访问控制
成员访问修饰符
class Person {
public: // 公有成员
string name;
protected: // 受保护成员
int age;
private: // 私有成员
string idCard;
};
3. 继承与多态
继承语法
class SavingsAccount : public BankAccount {
private:
double interestRate;
public:
SavingsAccount(string accNo, double initialBalance, double rate)
: BankAccount(accNo, initialBalance), interestRate(rate) {}
void addInterest() {
balance += balance * interestRate / 100;
}
};
三、???? 代码实战:银行账户管理系统
1. 功能需求
- 创建不同类型的账户(储蓄/支票)
- 存款/取款操作
- 计算利息(仅储蓄账户)
2. 实现步骤
#include <iostream>
#include <vector>
#include <string>
using namespace std;
class Account {
protected:
string accountNumber;
double balance;
public:
Account(string accNo, double amt)
: accountNumber(accNo), balance(amt) {}
virtual void display() const = 0; // 纯虚函数
};
class SavingsAccount : public Account {
private:
double interestRate;
public:
SavingsAccount(string accNo, double amt, double rate)
: Account(accNo, amt), interestRate(rate) {}
void deposit(double amt) {
balance += amt;
}
void withdraw(double amt) {
if (balance >= amt) {
balance -= amt;
}
}
void addInterest() {
balance += balance * interestRate / 100;
}
void display() const override {
cout << "储蓄账户(" << accountNumber << "):余额$" << balance << endl;
}
};
class CheckingAccount : public Account {
public:
CheckingAccount(string accNo, double amt)
: Account(accNo, amt) {}
void deposit(double amt) {
balance += amt;
}
bool withdraw(double amt) {
if (balance >= amt) {
balance -= amt;
return true;
}
return false;
}
void display() const override {
cout << "支票账户(" << accountNumber << "):余额$" << balance << endl;
}
};
int main() {
vector<Account*> accounts;
// 创建账户
accounts.push_back(new SavingsAccount("SA123", 5000, 2.5));
accounts.push_back(new CheckingAccount("CA456", 2000));
// 存款操作
accounts[0]->deposit(1000);
accounts[1]->deposit(500);
// 取款操作
accounts[0]->withdraw(200);
accounts[1]->withdraw(1500); // 余额不足
// 显示所有账户
cout << "\n???? 账户信息:" << endl;
for (const auto& acc : accounts) {
acc->display();
}
// 清理内存
for (auto acc : accounts) {
delete acc;
}
return 0;
}
四、????️ 进阶技巧
1. 构造函数初始化列表
class Point {
public:
Point(double x, double y)
: x(x), y(y) {} // 直接初始化成员变量
private:
double x, y;
};
2. 多态实现原理
// 纯虚函数声明
virtual void draw() = 0;
// 重写(override)关键字(C++11)
void draw() override;
3. 抽象类与接口
class Shape { // 抽象类
public:
virtual void draw() = 0; // 纯虚函数
};
class Circle : public Shape {
public:
void draw() override { /* 绘制圆 */ }
};
五、❓ 常见问题解答
Q:类和结构体有什么本质区别?
→ 默认访问权限不同(类private/结构体public),设计意图不同(类强调封装/结构体侧重数据组织)
Q:什么是虚函数?
→ 用于实现多态机制的成员函数,通过virtual关键字声明
Q:构造函数可以调用虚函数吗?
→ 不建议,此时虚函数调用的是基类的实现而非派生类
六、???? 今日总结
✅ 成功掌握:
- ???? 类的定义与对象创建方法
- ???? 封装实现数据隐藏
- ???? 继承与多态的基本应用
- ???? 构造函数/析构函数的编写规范
⏳ 明日预告:
- 模板编程基础(泛型编程)
七、???? 课后挑战任务
1.???? 完善银行系统:
- 添加账户类型判断功能
- 实现按账户类型统计总金额
2. ???? 抽象类应用:
// 完成图形面积计算程序
class Shape {
public:
virtual double area() = 0;
};
class Circle : public Shape {
private:
double radius;
public:
Circle(double r) : radius(r) {}
double area() override { return 3.14 * radius * radius; }
};
class Rectangle : public Shape {
private:
double width, height;
public:
Rectangle(double w, double h) : width(w), height(h) {}
double area() override { return width * height; }
};
int main() {
Shape* shapes[2];
shapes[0] = new Circle(5);
shapes[1] = new Rectangle(4, 6);
cout << "总面积:" << shapes[0]->area() + shapes[1]->area() << endl;
// 释放内存
delete[] shapes;
return 0;
}
3.???? 技术总结:
- 列举面向对象编程的5个典型应用场景
???? 上一天课后挑战任务答案
任务1:图书馆管理系统扩展(知识点拆解)
???? 核心知识点
-
结构体扩展
- 在原有
LibraryBook
结构体中添加borrowerName
和isBorrowed
字段 - 示例代码:
struct LibraryBook { string isbn; string title; string author; double price; string borrowerName; bool isBorrowed; };
- 在原有
-
动态数据管理
- 使用
vector<LibraryBook>
存储图书信息 - 添加借阅逻辑:
// 借阅操作 void borrowBook(vector<LibraryBook>& books, const string& isbn, const string& name) { for (auto& book : books) { if (book.isbn == isbn && !book.isBorrowed) { book.borrowerName = name; book.isBorrowed = true; cout << "????《" << book.title << "》已借出!" << endl; return; } } cout << "???? 该书不可借阅或已被借出!" << endl; }
- 使用
-
范围查询实现
- 按价格区间筛选图书:
vector<LibraryBook> filterByPrice(const vector<LibraryBook>& books, double minPrice, double maxPrice) { vector<LibraryBook> result; for (const auto& book : books) { if (book.price >= minPrice && book.price <= maxPrice) { result.push_back(book); } } return result; }
- 按价格区间筛选图书:
????️ 实现技巧
- 数据持久化:使用文件流保存借阅记录(
fstream
) - 界面优化:添加菜单循环和输入验证
- 异常处理:处理无效ISBN输入(
cin.fail()
)
任务2:时间格式转换程序(深入解析)
???? 关键知识点
-
联合体(Union)的特性
- 所有成员共享同一块内存地址
- 示例内存布局:
totalSeconds (int) | hours (int) | minutes (int) | seconds (int) ----------------------------------------------- 0x0000 | 0x0004 | 0x0008 | 0x000C
-
类型转换方法
- 通过成员访问符切换不同视图:
Time t; t.totalSeconds = 3661; // 初始化为总秒数 cout << "小时:" << t.hours << endl; // 自动转换显示
- 通过成员访问符切换不同视图:
-
取模运算原理
- 计算时分秒的数学公式:
hours = totalSeconds / 3600 remaining = totalSeconds % 3600 minutes = remaining / 60 seconds = remaining % 60
- 计算时分秒的数学公式:
???? 进阶应用
- 时区转换:添加时区偏移量参数
- 闰年判断:扩展日期计算功能
- 时间格式化:输出ISO 8601标准格式(
YYYY-MM-DD HH:MM:SS
)
任务3:技术总结表(知识点扩展)
应用场景 | 结构体设计要点 | 实际开发建议 |
---|---|---|
学生信息管理 | 包含学号/姓名/成绩/年级 | 使用std::vector 存储动态数据 |
几何图形计算 | 包含坐标/面积/周长 | 重载运算符(如+ 表示向量相加) |
文件元数据存储 | 包含创建时间/修改时间/大小 | 使用struct 代替class 提升效率 |
通信协议解析 | 包含版本号/数据长度/校验和 | 添加序列化(serialization)功能 |
???? 内存对比示意图
// 结构体内存布局示例
struct Student {
int id; // 4 bytes
char name[20]; // 20 bytes
float score; // 4 bytes
};
// 联合体内存布局示例
union Data {
int integer; // 4 bytes
double floating; // 8 bytes
char character; // 1 byte
};