学而时习之:C++中的面向对象编程

63 阅读4分钟

C++ 面向对象编程

在 OOP (Object-Oriented Programming) 出现之前,程序大多采用过程式思路:一步步写函数。代码一多,就难以管理、难以复用。

C++ 引入 OOP(Object-Oriented Programming),把代码划分成类与对象,让程序更易懂、易复用、易维护。

OOP 的核心价值

  • 把代码拆成逻辑单元(类/对象)
  • 把数据和方法封在一起(封装)
  • 模块化、可扩展、可复用
  • 防止外部非法访问

1. 类(Class)

类是用户定义的蓝图模板,用来创建对象。它把同一类事物共有的数据行为打包在一起,避免重复写代码。

一个 C++ 类声明通常包含以下要素:

  • 访问限定符(access specifiers)
    public / private / protected —— 控制外部能否访问成员。

  • 类名(class name)
    遵循大驼峰命名,如 StudentBankAccount

  • 类体(body)
    {} 包围,内部定义数据成员(变量)和成员函数(方法)。

图片翻译与重新生成.png

2. 对象(Object)

对象是面向对象程序的基本单元,用来模拟现实实体。一个 C++ 程序通常创建很多对象,它们通过调用彼此的方法完成工作。对象包含四个核心部分:

  1. 状态(State)
    由数据成员(属性)表示,反映对象的当前值。

  2. 成员函数(Member Function)
    对象能执行的操作,可返回结果给调用者。

  3. 行为(Behavior)
    成员函数的总体表现,体现对象对外界的“响应”。

  4. 身份(Identity)
    对象在内存中的唯一地址或引用,用于与其他对象交互。

示例:Employee 对象

#include <iostream>
#include <string>
using namespace std;

class Employee {
private:
    string name;
    float salary;

public:
    // 构造函数
    Employee(string name, float salary) {
        this->name = name;
        this->salary = salary;
    }

    // 读/写接口
    string getName() { return name; }
    float  getSalary() { return salary; }
    void setName(string name) { this->name = name; }
    void setSalary(float salary) { this->salary = salary; }

    // 展示对象状态
    void displayDetails() {
        cout << "Employee: " << name << endl;
        cout << "Salary: " << salary << endl;
    }
};

int main() {
    Employee emp("Geek", 10000.0f);  // 创建对象
    emp.displayDetails();            // 调用对象行为
    return 0;
}
Employee: Geek
Salary: 10000

3. 抽象(Abstraction)

抽象是指 把实现细节藏起来,只把必要的功能暴露给用户
这样,使用者只关心对象“能做什么”,而不必关心“怎么做”。

在 C++ 中,抽象通过 抽象类(即 至少含有一个纯虚函数 的类)来实现。

示例代码:

#include <iostream>
using namespace std;

// 抽象类:Vehicle
class Vehicle {
public:
    // 纯虚函数 → 抽象方法
    virtual void accelerate() = 0;
    virtual void brake()        = 0;

    // 普通成员函数
    void startEngine() {
        cout << "Engine started!" << endl;
    }
};

// 具体类:Car
class Car : public Vehicle {
public:
    void accelerate() override {
        cout << "Car: Pressing gas pedal..." << endl;
    }

    void brake() override {
        cout << "Car: Applying brakes..." << endl;
    }
};

int main() {
    // 用基类指针操作派生类对象
    Vehicle* myCar = new Car();
    myCar->startEngine();
    myCar->accelerate();
    myCar->brake();

    delete myCar;
    return 0;
}
Engine started!
Car: Pressing gas pedal...
Car: Applying brakes...

4. 封装(Encapsulation)

封装是指 把数据(变量)和操作数据的函数(方法)捆绑成一个整体——通常就是 类(class)
它像一道“保护盾”,阻止外部代码直接访问类内部的数据,从而避免意外修改或滥用。

技术上看:

  • 类里的变量声明为 private(私有)
  • 外部若想读写这些变量,必须通过类自己提供的 public 方法(即 getter/setter)

这样既能隐藏实现细节,又能控制访问权限,实现“数据隐藏”与“接口隔离”。

#include <iostream>
#include <string>
using namespace std;

class Employee {
    // Private fields 
private:
    int id;
    string name;
public:
    // Setter methods
    void setId(int id) {
        this->id = id;
    }

    void setName(string name) {
        this->name = name;
    }

    // Getter methods
    int getId() {
        return id;
    }

    string getName() {
        return name;
    }
};

int main() {
    Employee emp;
    // Using setters
    emp.setId(101);
    emp.setName("Geek");
    // Using getters
    cout << "Employee ID: " << emp.getId() << endl;
    cout << "Employee Name: " << emp.getName() << endl;
    return 0;
}

5. 继承(Inheritance)

继承是 OOP 的又一大支柱。它让一个类(子类)直接获得另一个类(父类)的数据成员和成员函数,无需重复编写。
语法:在子类名后加 : <访问级别> 父类名,常用 public 继承。

关键术语:

  • Superclass(父类/基类):被继承的类
  • Subclass(子类/派生类):继承别人的类,可额外添加自己的成员
  • 复用性(Reusability):写新类时,直接“扩展”已有类,代码不再重复

示例:Dog 继承 Animal

#include <iostream>
using namespace std;

// 父类
class Animal {
public:
    void eat()  { cout << "Animal is eating..."  << endl; }
    void sleep(){ cout << "Animal is sleeping..." << endl; }
};

// 子类:public 继承 Animal
class Dog : public Animal {
public:
    void bark() { cout << "Dog is barking!" << endl; }
};

int main() {
    Dog myDog;
    myDog.eat();   // 来自 Animal
    myDog.sleep(); // 来自 Animal
    myDog.bark();  // Dog 自有
    return 0;
}
Animal is eating...
Animal is sleeping...
Dog is barking!