第8天:面向对象编程入门 - 类与对象

时间:2025-03-01 07:17:40

第8天:面向对象编程入门 - 类与对象

一、???? 今日学习目标

  1. ???? 掌握类与对象的定义与使用
  2. ???? 理解封装、继承、多态三大特性
  3. ???? 完成银行账户管理系统实战
  4. ????️ 学会构造函数与析构函数的编写

二、⚙️ 核心知识点详解

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:图书馆管理系统扩展(知识点拆解)

???? 核心知识点
  1. 结构体扩展

    • 在原有LibraryBook结构体中添加borrowerNameisBorrowed字段
    • 示例代码:
      struct LibraryBook {
          string isbn;
          string title;
          string author;
          double price;
          string borrowerName;
          bool isBorrowed;
      };
      
  2. 动态数据管理

    • 使用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;
      }
      
  3. 范围查询实现

    • 按价格区间筛选图书:
      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:时间格式转换程序(深入解析)

???? 关键知识点
  1. 联合体(Union)的特性

    • 所有成员共享同一块内存地址
    • 示例内存布局:
      totalSeconds (int) | hours (int) | minutes (int) | seconds (int)
      -----------------------------------------------
      0x0000           | 0x0004       | 0x0008        | 0x000C
      
  2. 类型转换方法

    • 通过成员访问符切换不同视图:
      Time t;
      t.totalSeconds = 3661; // 初始化为总秒数
      cout << "小时:" << t.hours << endl; // 自动转换显示
      
  3. 取模运算原理

    • 计算时分秒的数学公式:
      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
};