19. 面向对象入门:类与对象、访问修饰符

面向对象编程,说白了就是把现实世界的东西映射到代码里。

我刚开始学C++那会儿,总觉得这东西玄乎。后来写多了才发现,它其实就是一种组织代码的思维方式。今天咱们就聊聊最核心的三个概念:对象,还有public/private/protected这三个访问修饰符。

什么是类?什么是对象?

你可以把理解成一张设计图纸,而对象就是按照这张图纸造出来的实物。

举个例子。你想想看,手机厂商要造一批手机,是不是先得有一份详细的设计文档?这份文档里规定了屏幕尺寸、电池容量、摄像头参数等等。这份文档就是「类」。而流水线上生产出来的每一台手机,就是「对象」。

核心区别:

  • :抽象的概念,不占内存空间
  • 对象:具体的实例,占用实际内存

在C++里,定义一个类用class关键字。我习惯把类的定义放在头文件里,这样结构清晰。

// 定义一个"手机"类
class Phone {
public:
    // 成员函数(方法)
    void call(const std::string& number) {
        std::cout << "正在拨打: " << number << std::endl;
    }
    
    void sendMessage(const std::string& msg) {
        std::cout << "发送短信: " << msg << std::endl;
    }

private:
    // 成员变量(属性)
    std::string brand;      // 品牌
    double screenSize;      // 屏幕尺寸
    int batteryLevel;       // 电量
};

有了类之后,创建对象就很简单了:

int main() {
    // 创建对象
    Phone myPhone;
    Phone yourPhone;
    
    // 调用成员函数
    myPhone.call("13800138000");
    yourPhone.sendMessage("你好!");
    
    return 0;
}

你看,myPhoneyourPhone是两个独立的对象,各自有各自的内存空间。你打电话不会影响我发短信,对吧?

访问修饰符:public、private、protected

这三个家伙,说白了就是控制谁能碰谁不能碰的「权限开关」。

我在项目中遇到过不少新手,上来就把所有成员都写成public。嗯,这样写确实省事,但后患无穷。你想想看,如果别人能随便修改你对象的内部数据,那程序迟早要崩。

修饰符 类内部 派生类 外部代码
public ✅ 可访问 ✅ 可访问 ✅ 可访问
protected ✅ 可访问 ✅ 可访问 ❌ 不可访问
private ✅ 可访问 ❌ 不可访问 ❌ 不可访问

public:对外开放的接口

凡是标记为public的成员,谁都能用。通常我们把成员函数(也就是方法)放在这里,作为对外提供的服务接口。

class BankAccount {
public:
    // 对外接口:存款
    void deposit(double amount) {
        if (amount > 0) {
            balance += amount;
        }
    }
    
    // 对外接口:查询余额
    double getBalance() const {
        return balance;
    }

private:
    double balance = 0.0;  // 余额对外隐藏
};

private:内部秘密

private成员只有类内部能访问。外部代码想碰?没门。

我个人的习惯是:所有成员变量默认都写成private。为什么?因为这样可以控制数据的读写方式。比如上面的balance,我不希望别人直接account.balance = 1000000这样乱改,必须通过deposit()函数来操作,这样我可以在函数里加校验逻辑。

小技巧:private封装数据,用public暴露接口。这就是所谓的「封装」——面向对象四大特性之一。

protected:留给子类的特权

protected介于两者之间。外部代码不能访问,但派生类(也就是子类)可以访问。

class Animal {
protected:
    int age;  // 子类可以访问
    
public:
    void eat() {
        std::cout << "吃东西" << std::endl;
    }
};

class Dog : public Animal {
public:
    void bark() {
        age = 3;  // ✅ 可以访问protected成员
        std::cout << "汪汪!我" << age << "岁了" << std::endl;
    }
};

注意:别滥用protected。我曾经在一个项目里看到有人把所有成员都写成protected,结果派生类里改来改去,数据乱成一锅粥。记住:能用private就别用protected

知识体系结构图

下面这张图帮你理清本章的核心脉络:

面向对象入门:类与对象 类 (Class) 实例化 对象 (Object) 包含 访问修饰符 public protected private 拥有 成员 成员变量 成员函数 封装:将数据和操作数据的方法捆绑在一起,对外隐藏内部实现细节 public → 对外接口 protected → 子类特权 private → 内部秘密

避坑指南

我曾经在一个金融项目里接手过一段代码,那个类的所有成员变量都是public的。结果呢?业务逻辑散落在各个地方,谁都能改数据,出了bug根本查不到是谁改的。最后花了整整两周重构,把所有成员变量改成private,加上getter/setter,代码才稳定下来。

所以我的建议是:

  • 成员变量:一律private,通过getter/setter访问
  • 成员函数:对外接口用public,内部辅助函数用private
  • 派生类需要访问的:才考虑用protected

记住一句话:能藏起来的就别露出来。封装得越好,代码越容易维护。

好了,关于类、对象和访问修饰符,今天就聊到这儿。这些东西看着简单,但真正用好需要多写多练。下次写代码的时候,不妨多想想:这个成员该不该让别人看到?


公众号:蓝海资料掘金营,微信deep3321