以下是为零基础学习者设计的面向对象思想教程,以通俗易懂的语言和示例讲解核心概念:

一、什么是面向对象思想?

一句话理解
把现实世界中的事物(如汽车、学生、手机)抽象成程序中的“对象”,每个对象包含自己的数据(属性)和行为(方法)。

对比面向过程

  • 面向过程:关注“怎么做”,用函数一步步解决问题(如先打开冰箱→放东西→关冰箱)。
  • 面向对象:关注“谁来做”,将功能封装到对象中(如冰箱对象有open()store()close()方法)。

二、核心概念

1. 对象(Object)

  • 定义:现实事物的抽象,如一个具体的学生、一辆汽车。
  • 组成
    • 属性(数据):学生的姓名、年龄;汽车的颜色、速度。
    • 方法(行为):学生学习()、汽车加速()

示例

// 定义一个“学生”类(蓝图)
class Student {
public:
    // 属性
    string name;
    int age;

    // 方法
    void study() {
        cout << name << "正在学习!" << endl;
    }
};

// 创建对象(实例)
Student tom;
tom.name = "Tom";
tom.age = 18;
tom.study(); // 输出:Tom正在学习!

2. 类(Class)

  • 定义:对象的模板,描述同类对象的共同属性和方法。
  • 作用:避免重复代码,提高复用性。

示例

class Car {
public:
    string color;
    int speed;

    void accelerate() {
        speed += 10;
        cout << "加速后速度:" << speed << endl;
    }
};

3. 封装(Encapsulation)

  • 定义:将数据和方法“打包”成一个整体,隐藏内部细节,只暴露必要接口。
  • 好处:保护数据安全,降低代码复杂度。

示例

class BankAccount {
private: // 私有属性,外部无法直接访问
    double balance;

public:
    // 提供公共方法操作私有数据
    void deposit(double amount) {
        if (amount > 0) balance += amount;
    }

    double getBalance() {
        return balance;
    }
};

4. 继承(Inheritance)

  • 定义:子类自动获得父类的属性和方法,并可扩展新功能。
  • 语法class 子类 : 继承方式 父类 { ... }
  • 作用:减少重复代码,体现“is-a”关系(如学生是一个人)。

示例

class Person {
public:
    string name;
    void eat() { cout << name << "在吃饭。" << endl; }
};

// 学生类继承自Person
class Student : public Person {
public:
    int studentID;
    void study() { cout << name << "在学习。" << endl; }
};

// 使用
Student tom;
tom.name = "Tom";
tom.eat(); // 继承自Person
tom.study(); // 学生特有的方法

5. 多态(Polymorphism)

  • 定义:同一方法在不同对象中表现不同行为。
  • 实现方式
    • 函数重载(静态多态):同一函数名,不同参数。
    • 虚函数(动态多态):通过基类指针调用子类方法。

示例(动态多态)

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; }
};

// 使用
Animal* animal1 = new Dog();
Animal* animal2 = new Cat();
animal1->speak(); // 输出:汪汪!
animal2->speak(); // 输出:喵喵!

三、为什么选择面向对象?

  1. 代码复用性:通过继承减少重复代码。
  2. 可维护性:封装使代码结构清晰,修改方便。
  3. 扩展性:新增功能时只需添加新类,无需修改原有代码。

四、实践建议

  1. 从简单类开始:如PersonCar,练习属性和方法定义。
  2. 尝试继承:创建Student继承Person,添加新属性和方法。
  3. 理解多态:用基类指针调用子类方法,观察不同行为。

五、总结

  • 核心思想:万物皆对象,对象封装数据与行为,通过继承和多态实现灵活扩展。
  • 关键原则:封装(保护数据)、继承(代码复用)、多态(行为多样)。

通过实践和示例,逐步掌握面向对象思想,能显著提升代码的质量和开发效率。

5 条评论

  • @ 2025-3-13 22:03:20

    在C++里,类的私有成员变量和函数只能在类的内部被访问,类的外部不能直接访问。不过,我们可以通过一些特定的方法在类的外部间接访问这些私有成员。下面为你详细介绍几种常见的方法:

    1. 使用公有成员函数(访问器和修改器)

    可以在类中定义公有成员函数,通过这些函数来访问和修改私有成员。其中,用于获取私有成员值的函数被称为访问器(getter),用于修改私有成员值的函数被称为修改器(setter)。

    示例代码

    #include <iostream>
    #include <string>
    
    class Person {
    private:
        std::string name;
        int age;
    
    public:
        // 访问器函数,用于获取 name 的值
        std::string getName() const {
            return name;
        }
        // 访问器函数,用于获取 age 的值
        int getAge() const {
            return age;
        }
        // 修改器函数,用于设置 name 的值
        void setName(const std::string& n) {
            name = n;
        }
        // 修改器函数,用于设置 age 的值
        void setAge(int a) {
            if (a > 0) {
                age = a;
            }
        }
    };
    
    int main() {
        Person person;
        // 通过修改器设置私有成员的值
        person.setName("张三");
        person.setAge(20);
        // 通过访问器获取私有成员的值
        std::cout << "姓名: " << person.getName() << std::endl;
        std::cout << "年龄: " << person.getAge() << std::endl;
        return 0;
    }
    

    代码解释

    • getName()getAge() 是访问器函数,它们可以在类的外部调用,用于获取私有成员 nameage 的值。
    • setName()setAge() 是修改器函数,通过这些函数可以在类的外部修改私有成员的值。同时,在 setAge() 函数中还可以添加一些逻辑判断,比如确保年龄为正数。

    2. 使用友元函数或友元类

    友元机制能够打破类的封装性,允许特定的函数或类访问该类的私有成员。

    2.1 友元函数

    示例代码

    #include <iostream>
    #include <string>
    
    class Person {
    private:
        std::string name;
        int age;
    
    public:
        Person(const std::string& n, int a) : name(n), age(a) {}
    
        // 声明友元函数
        friend void printPersonInfo(const Person& p);
    };
    
    // 友元函数的定义
    void printPersonInfo(const Person& p) {
        std::cout << "姓名: " << p.name << ", 年龄: " << p.age << std::endl;
    }
    
    int main() {
        Person person("李四", 25);
        // 调用友元函数访问私有成员
        printPersonInfo(person);
        return 0;
    }
    

    代码解释

    • Person 类中,使用 friend 关键字声明 printPersonInfo() 为友元函数。
    • 友元函数 printPersonInfo() 可以直接访问 Person 类的私有成员 nameage

    2.2 友元类

    示例代码

    #include <iostream>
    #include <string>
    
    class Person {
    private:
        std::string name;
        int age;
    
    public:
        Person(const std::string& n, int a) : name(n), age(a) {}
    
        // 声明友元类
        friend class FriendClass;
    };
    
    class FriendClass {
    public:
        void printPersonInfo(const Person& p) {
            std::cout << "姓名: " << p.name << ", 年龄: " << p.age << std::endl;
        }
    };
    
    int main() {
        Person person("王五", 30);
        FriendClass friendObj;
        // 通过友元类的成员函数访问私有成员
        friendObj.printPersonInfo(person);
        return 0;
    }
    

    代码解释

    • Person 类中,使用 friend 关键字声明 FriendClass 为友元类。
    • FriendClass 类的成员函数 printPersonInfo() 可以直接访问 Person 类的私有成员。

    总结

    • 使用公有成员函数(访问器和修改器)是最常用的方法,它遵循了类的封装原则,并且可以对私有成员的访问进行控制。
    • 友元函数和友元类虽然可以方便地访问私有成员,但会破坏类的封装性,应谨慎使用。通常在必要的情况下,比如实现一些特殊的功能或优化性能时才会使用。
    • @ 2025-3-13 22:02:49

      在C++里,类的访问修饰符主要有三种,分别是publicprivateprotected,它们在控制类成员(包括成员变量和成员函数)的访问权限方面发挥着重要作用。下面为你详细介绍这三种访问修饰符:

      1. public(公有)访问修饰符

      • 作用:被public修饰的成员能够在类的内部、类的外部以及派生类中被访问。它为类与外部代码之间提供了交互的接口,使得外部代码可以直接调用类的公有成员。
      • 示例代码
      #include <iostream>
      class MyClass {
      public:
          // 公有成员变量
          int publicVar;
          // 公有成员函数
          void publicFunction() {
              std::cout << "这是一个公有成员函数。" << std::endl;
          }
      };
      
      int main() {
          MyClass obj;
          // 可以在类外部访问公有成员变量
          obj.publicVar = 10;
          std::cout << "公有成员变量的值: " << obj.publicVar << std::endl;
          // 可以在类外部调用公有成员函数
          obj.publicFunction();
          return 0;
      }
      
      • 代码解释:在这个示例中,publicVarpublicFunction()都是公有成员。在main函数里,也就是类的外部,能够直接访问publicVar并对其赋值,还可以调用publicFunction()

      2. private(私有)访问修饰符

      • 作用:被private修饰的成员只能在类的内部被访问,类的外部和派生类都无法直接访问。这有助于保护类的数据不被外部随意修改,增强了类的封装性和数据安全性。
      • 示例代码
      #include <iostream>
      class MyClass {
      private:
          // 私有成员变量
          int privateVar;
          // 私有成员函数
          void privateFunction() {
              std::cout << "这是一个私有成员函数。" << std::endl;
          }
      public:
          // 公有成员函数,用于访问私有成员
          void accessPrivate() {
              privateVar = 20;
              std::cout << "私有成员变量的值: " << privateVar << std::endl;
              privateFunction();
          }
      };
      
      int main() {
          MyClass obj;
          // 不能在类外部直接访问私有成员
          // obj.privateVar = 10;  // 错误
          // obj.privateFunction();  // 错误
          // 可以通过公有成员函数间接访问私有成员
          obj.accessPrivate();
          return 0;
      }
      
      • 代码解释privateVarprivateFunction()是私有成员。在main函数中,若尝试直接访问它们会引发编译错误。不过,可以通过类的公有成员函数accessPrivate()来间接访问这些私有成员。

      3. protected(受保护)访问修饰符

      • 作用:被protected修饰的成员可以在类的内部以及派生类中被访问,但在类的外部不能直接访问。它为派生类提供了一定的访问权限,同时又限制了外部代码的直接访问。
      • 示例代码
      #include <iostream>
      class BaseClass {
      protected:
          // 受保护成员变量
          int protectedVar;
          // 受保护成员函数
          void protectedFunction() {
              std::cout << "这是一个受保护成员函数。" << std::endl;
          }
      };
      
      class DerivedClass : public BaseClass {
      public:
          // 派生类的公有成员函数,用于访问基类的受保护成员
          void accessProtected() {
              protectedVar = 30;
              std::cout << "受保护成员变量的值: " << protectedVar << std::endl;
              protectedFunction();
          }
      };
      
      int main() {
          DerivedClass obj;
          // 不能在类外部直接访问受保护成员
          // obj.protectedVar = 10;  // 错误
          // obj.protectedFunction();  // 错误
          // 可以通过派生类的公有成员函数间接访问受保护成员
          obj.accessProtected();
          return 0;
      }
      
      • 代码解释protectedVarprotectedFunction()是受保护成员。在main函数中无法直接访问这些成员。但在DerivedClass这个派生类里,能够直接访问基类的受保护成员,比如在accessProtected()函数中就可以对其进行操作。

      总结

      • public访问修饰符让成员可以在类的任何地方被访问,常用于提供类与外部交互的接口。
      • private访问修饰符将成员的访问权限限制在类的内部,有助于保证数据的安全性和封装性。
      • protected访问修饰符允许成员在类的内部和派生类中被访问,在实现继承关系时非常有用。
      • @ 2025-3-13 22:01:58

        1. 面向对象编程思想概述

        面向对象编程(Object - Oriented Programming,OOP)是一种编程范式,它将数据和操作数据的方法封装在一起,形成对象。这种编程方式模拟了现实世界中事物的行为和关系,让代码更易于理解、维护和扩展。

        与传统的面向过程编程不同,面向过程编程关注的是解决问题的步骤,而面向对象编程关注的是参与问题解决的对象。例如,在一个学校管理系统中,面向过程编程可能会编写一系列函数来处理学生的注册、成绩管理等;而面向对象编程会将学生、教师等抽象成对象,每个对象有自己的属性(如学生的姓名、学号)和方法(如学生的学习、考试)。

        2. 类的基本概念

        类是对象的蓝图或模板,它定义了对象的属性(成员变量)和行为(成员函数)。可以把类想象成一个制造产品的模具,通过这个模具可以生产出多个具有相同属性和行为的产品(对象)。

        3. 类的创建与使用

        3.1 简单类的创建

        下面是一个简单的 Person 类的示例:

        #include <iostream>
        #include <string>
        
        // 定义 Person 类
        class Person {
        private:
            // 私有成员变量,外部不能直接访问
            std::string name;
            int age;
        
        public:
            // 构造函数,用于初始化对象
            Person(const std::string& n, int a) {
                name = n;
                age = a;
            }
        
            // 成员函数,用于显示个人信息
            void displayInfo() {
                std::cout << "姓名: " << name << ", 年龄: " << age << std::endl;
            }
        };
        
        int main() {
            // 创建 Person 对象
            Person person1("张三", 20);
            // 调用对象的成员函数
            person1.displayInfo();
        
            return 0;
        }
        

        代码解释:

        • 类的定义:使用 class 关键字定义一个类,后面跟着类的名称(这里是 Person)。
        • 私有成员变量nameage 是私有成员变量,只能在类的内部访问,这样可以保护数据不被外部随意修改。
        • 构造函数Person(const std::string& n, int a) 是构造函数,它的名称和类名相同,没有返回类型。构造函数在创建对象时自动调用,用于初始化对象的成员变量。
        • 成员函数displayInfo() 是一个公有成员函数,用于输出对象的信息。公有成员可以在类的外部访问。
        • 对象的创建和使用:在 main 函数中,使用构造函数创建了一个 Person 对象 person1,并调用了它的 displayInfo() 函数。

        3.2 访问控制

        在 C++ 中,类的成员可以有不同的访问权限,主要有三种:

        • private(私有):私有成员只能在类的内部访问,外部无法直接访问。这有助于保护数据的安全性。
        • public(公有):公有成员可以在类的外部访问,通常用于提供与外部交互的接口。
        • protected(受保护):受保护成员可以在类的内部和派生类中访问,在类的外部不能直接访问。

        3.3 析构函数

        析构函数是一种特殊的成员函数,它在对象销毁时自动调用,用于释放对象占用的资源。析构函数的名称是在类名前加上 ~

        #include <iostream>
        #include <string>
        
        class Person {
        private:
            std::string name;
            int age;
        
        public:
            Person(const std::string& n, int a) {
                name = n;
                age = a;
                std::cout << "创建了一个 Person 对象: " << name << std::endl;
            }
        
            // 析构函数
            ~Person() {
                std::cout << "销毁了一个 Person 对象: " << name << std::endl;
            }
        
            void displayInfo() {
                std::cout << "姓名: " << name << ", 年龄: " << age << std::endl;
            }
        };
        
        int main() {
            {
                Person person2("李四", 25);
                person2.displayInfo();
            } // 离开这个作用域,person2 对象被销毁
        
            return 0;
        }
        

        4. 类的继承

        继承是面向对象编程的一个重要特性,它允许一个类(子类)继承另一个类(父类)的属性和方法。子类可以在父类的基础上进行扩展或修改。

        #include <iostream>
        #include <string>
        
        // 父类:Person
        class Person {
        protected:
            std::string name;
            int age;
        
        public:
            Person(const std::string& n, int a) : name(n), age(a) {}
        
            void displayInfo() {
                std::cout << "姓名: " << name << ", 年龄: " << age << std::endl;
            }
        };
        
        // 子类:Student,继承自 Person
        class Student : public Person {
        private:
            std::string studentID;
        
        public:
            Student(const std::string& n, int a, const std::string& id) : Person(n, a), studentID(id) {}
        
            void displayStudentInfo() {
                displayInfo();
                std::cout << "学号: " << studentID << std::endl;
            }
        };
        
        int main() {
            Student student1("王五", 22, "2023001");
            student1.displayStudentInfo();
        
            return 0;
        }
        

        代码解释:

        • 父类Person 类是父类,包含 nameage 两个成员变量以及 displayInfo() 成员函数。
        • 子类Student 类继承自 Person 类,使用 public 继承方式。子类除了继承父类的属性和方法外,还添加了自己的成员变量 studentID 和成员函数 displayStudentInfo()
        • 子类的构造函数:子类的构造函数需要调用父类的构造函数来初始化从父类继承的成员变量。

        5. 多态

        多态是指不同的对象对同一个消息做出不同的响应。在 C++ 中,多态主要通过虚函数和继承来实现。

        #include <iostream>
        #include <string>
        
        // 基类:Shape
        class Shape {
        public:
            // 虚函数
            virtual void draw() {
                std::cout << "绘制一个形状" << std::endl;
            }
        };
        
        // 子类:Circle,继承自 Shape
        class Circle : public Shape {
        public:
            // 重写基类的虚函数
            void draw() override {
                std::cout << "绘制一个圆形" << std::endl;
            }
        };
        
        // 子类:Rectangle,继承自 Shape
        class Rectangle : public Shape {
        public:
            // 重写基类的虚函数
            void draw() override {
                std::cout << "绘制一个矩形" << std::endl;
            }
        };
        
        // 多态函数
        void drawShape(Shape& shape) {
            shape.draw();
        }
        
        int main() {
            Circle circle;
            Rectangle rectangle;
        
            drawShape(circle);
            drawShape(rectangle);
        
            return 0;
        }
        

        代码解释:

        • 虚函数:在基类 Shape 中,draw() 函数被声明为虚函数。虚函数允许在派生类中重写该函数。
        • 重写CircleRectangle 类分别重写了 draw() 函数,实现了不同的绘制行为。
        • 多态调用drawShape() 函数接受一个 Shape 类的引用,根据传入的实际对象类型,调用相应的 draw() 函数。

        6. 总结

        通过以上内容,你学习了 C++ 中面向对象编程的基本概念,包括类的创建、访问控制、构造函数、析构函数、继承和多态等。这些特性使得代码更加模块化、可复用和易于维护。在实际编程中,你可以根据具体需求灵活运用这些特性来设计和实现复杂的程序。

        • @ 2025-3-13 22:01:07

          1. 理解面向对象编程思想

          在传统编程中,我们更关注解决问题的具体步骤,就像按照一份详细的说明书来组装一个玩具,一步一步按顺序操作。而面向对象编程(Object - Oriented Programming,OOP)则是把现实世界中的事物抽象成程序里的对象,更注重“谁”来完成这些操作。

          举个例子,假如要开发一个学校管理系统。在面向过程编程里,我们可能会写一系列的函数来处理学生的注册、成绩录入等操作。而在面向对象编程中,我们会把学生、老师等抽象成对象,每个对象都有自己的属性(如学生的姓名、年龄、学号)和方法(如学生的学习、考试等行为)。

          2. 类的概念

          类是对象的蓝图或模板,它定义了对象的属性和方法。可以把类想象成制作蛋糕的模具,通过这个模具可以制作出很多相同类型的蛋糕(对象)。

          3. 创建一个简单的类

          下面我们来创建一个简单的 Person 类,这个类包含人的基本属性(姓名和年龄)和一个方法(介绍自己)。

          #include <iostream>
          #include <string>
          
          // 定义 Person 类
          class Person {
              // 私有成员,外部不能直接访问
          private:
              std::string name;
              int age;
          
              // 公有成员,外部可以访问
          public:
              // 构造函数,用于初始化对象
              Person(const std::string& n, int a) {
                  name = n;
                  age = a;
              }
          
              // 方法:介绍自己
              void introduce() {
                  std::cout << "我叫 " << name << ",今年 " << age << " 岁。" << std::endl;
              }
          };
          
          int main() {
              // 创建 Person 对象
              Person person1("张三", 20);
              // 调用对象的方法
              person1.introduce();
          
              return 0;
          }
          

          代码解释:

          • 类的定义:使用 class 关键字定义一个类,后面跟着类的名称(这里是 Person)。
          • 成员变量:在类的内部,我们定义了两个私有成员变量 nameage。私有成员只能在类的内部访问,这样可以保证数据的安全性。
          • 构造函数:构造函数是一种特殊的方法,它的名称和类名相同,没有返回类型。构造函数在创建对象时自动调用,用于初始化对象的成员变量。在上面的代码中,Person(const std::string& n, int a) 就是构造函数,它接受两个参数,分别用于初始化 nameage
          • 成员方法introduce() 是一个公有成员方法,用于输出对象的信息。公有成员可以在类的外部访问。
          • 创建对象:在 main 函数中,我们使用构造函数创建了一个 Person 对象 person1,并调用了它的 introduce() 方法。

          4. 访问控制

          在 C++ 中,类的成员可以有不同的访问权限,主要有三种:

          • private(私有):私有成员只能在类的内部访问,外部无法直接访问。这有助于保护数据不被外部随意修改。
          • public(公有):公有成员可以在类的外部访问,通常用于提供与外部交互的接口。
          • protected(受保护):受保护成员可以在类的内部和派生类中访问,在类的外部不能直接访问。

          5. 类的更多特性

          5.1 析构函数

          析构函数是一种特殊的成员函数,它在对象销毁时自动调用,用于释放对象占用的资源。析构函数的名称是在类名前加上 ~

          #include <iostream>
          #include <string>
          
          class Person {
          private:
              std::string name;
              int age;
          
          public:
              Person(const std::string& n, int a) {
                  name = n;
                  age = a;
                  std::cout << "创建了一个 Person 对象:" << name << std::endl;
              }
          
              // 析构函数
              ~Person() {
                  std::cout << "销毁了一个 Person 对象:" << name << std::endl;
              }
          
              void introduce() {
                  std::cout << "我叫 " << name << ",今年 " << age << " 岁。" << std::endl;
              }
          };
          
          int main() {
              {
                  Person person2("李四", 25);
                  person2.introduce();
              } // 离开这个作用域,person2 对象被销毁
          
              return 0;
          }
          

          5.2 成员函数重载

          成员函数重载是指在一个类中可以定义多个同名的成员函数,但它们的参数列表不同。编译器会根据调用时传递的参数来决定调用哪个函数。

          #include <iostream>
          #include <string>
          
          class Calculator {
          public:
              // 加法函数,两个整数相加
              int add(int a, int b) {
                  return a + b;
              }
          
              // 加法函数,两个浮点数相加
              double add(double a, double b) {
                  return a + b;
              }
          };
          
          int main() {
              Calculator calc;
              std::cout << "整数相加结果:" << calc.add(3, 5) << std::endl;
              std::cout << "浮点数相加结果:" << calc.add(3.2, 5.7) << std::endl;
          
              return 0;
          }
          

          6. 总结

          通过以上内容,你应该对面向对象编程思想和类的创建有了基本的了解。类是面向对象编程的核心概念,它将数据和操作封装在一起,提高了代码的可维护性和复用性。在实际编程中,你可以根据需要创建不同的类,并利用类的各种特性来实现复杂的功能。

          • @ 2025-3-13 22:00:11

            1. 什么是面向对象编程

            在传统的编程模式(面向过程编程)中,我们更关注解决问题的步骤,就像按照一份详细的菜谱做菜,一步一步地完成各项操作。而面向对象编程(Object - Oriented Programming,OOP)则是把现实世界中的事物抽象成程序中的对象,更关注“谁”来做这些事。比如,在一个学校管理系统里,我们可以把学生、老师等抽象成对象,每个对象都有自己的特征(属性)和能做的事情(方法)。

            2. 面向对象的四大特性

            2.1 封装

            封装就像是把一个事物包装起来,只对外提供必要的接口,隐藏内部的实现细节。这样做的好处是提高了数据的安全性,同时也让代码的维护更加方便。

            示例代码

            #include <iostream>
            #include <string>
            
            class BankAccount {
            private:
                // 私有属性,外部无法直接访问
                double balance;
                std::string accountNumber;
            
            public:
                // 构造函数,用于初始化对象
                BankAccount(const std::string& accNum, double initialBalance)
                    : accountNumber(accNum), balance(initialBalance) {}
            
                // 公共方法,用于存款
                void deposit(double amount) {
                    if (amount > 0) {
                        balance += amount;
                        std::cout << "存款成功,当前余额: " << balance << std::endl;
                    } else {
                        std::cout << "存款金额必须大于 0。" << std::endl;
                    }
                }
            
                // 公共方法,用于取款
                void withdraw(double amount) {
                    if (amount > 0 && amount <= balance) {
                        balance -= amount;
                        std::cout << "取款成功,当前余额: " << balance << std::endl;
                    } else {
                        std::cout << "取款失败,余额不足或取款金额无效。" << std::endl;
                    }
                }
            
                // 公共方法,用于查询余额
                double getBalance() const {
                    return balance;
                }
            };
            
            int main() {
                BankAccount myAccount("123456", 1000.0);
                myAccount.deposit(500.0);
                myAccount.withdraw(200.0);
                std::cout << "当前余额: " << myAccount.getBalance() << std::endl;
                return 0;
            }
            

            代码解释

            • BankAccount 类将 balanceaccountNumber 作为私有属性,外部代码不能直接访问和修改这些属性,只能通过类提供的公共方法(如 depositwithdrawgetBalance)来操作。这样可以防止外部代码对数据进行非法修改,保证了数据的安全性。

            2.2 继承

            继承允许一个类(子类)继承另一个类(父类)的属性和方法,子类可以在此基础上添加自己的特性或修改父类的行为。继承的主要作用是实现代码的复用,避免重复编写相同的代码。

            示例代码

            #include <iostream>
            #include <string>
            
            // 父类:动物
            class Animal {
            protected:
                std::string name;
            
            public:
                Animal(const std::string& n) : name(n) {}
            
                // 父类的方法
                void eat() {
                    std::cout << name << " 正在吃东西。" << std::endl;
                }
            };
            
            // 子类:狗,继承自动物类
            class Dog : public Animal {
            public:
                Dog(const std::string& n) : Animal(n) {}
            
                // 子类自己的方法
                void bark() {
                    std::cout << name << " 正在汪汪叫。" << std::endl;
                }
            };
            
            int main() {
                Dog myDog("旺财");
                myDog.eat();  // 调用从父类继承的方法
                myDog.bark(); // 调用子类自己的方法
                return 0;
            }
            

            代码解释

            • Dog 类继承自 Animal 类,因此 Dog 类的对象可以使用 Animal 类中定义的 eat 方法。同时,Dog 类还定义了自己的 bark 方法,这体现了子类可以在父类的基础上进行扩展。

            2.3 多态

            多态意味着不同的对象可以对同一个消息做出不同的响应。在 C++ 中,多态主要通过虚函数和继承来实现。

            示例代码

            #include <iostream>
            #include <string>
            
            // 基类:形状
            class Shape {
            public:
                // 虚函数
                virtual void draw() {
                    std::cout << "绘制一个形状。" << std::endl;
                }
            };
            
            // 子类:圆形
            class Circle : public Shape {
            public:
                // 重写基类的虚函数
                void draw() override {
                    std::cout << "绘制一个圆形。" << std::endl;
                }
            };
            
            // 子类:矩形
            class Rectangle : public Shape {
            public:
                // 重写基类的虚函数
                void draw() override {
                    std::cout << "绘制一个矩形。" << std::endl;
                }
            };
            
            // 多态函数
            void drawShape(Shape& shape) {
                shape.draw();
            }
            
            int main() {
                Circle circle;
                Rectangle rectangle;
            
                drawShape(circle);
                drawShape(rectangle);
                return 0;
            }
            

            代码解释

            • Shape 类中的 draw 方法被声明为虚函数,CircleRectangle 类分别重写了这个方法。在 drawShape 函数中,通过基类引用调用 draw 方法,根据传入的实际对象类型,会调用相应子类的 draw 方法,这就是多态的体现。

            2.4 抽象

            抽象是指从具体的事物中提取出共同的特征和行为,形成一个抽象的概念。在 C++ 中,抽象通常通过抽象类和纯虚函数来实现。抽象类不能被实例化,它主要用于作为其他类的基类,提供一个通用的接口。

            示例代码

            #include <iostream>
            
            // 抽象类:交通工具
            class Vehicle {
            public:
                // 纯虚函数
                virtual void move() = 0;
            
                // 普通成员函数
                void display() {
                    std::cout << "这是一个交通工具。" << std::endl;
                }
            };
            
            // 子类:汽车
            class Car : public Vehicle {
            public:
                // 实现纯虚函数
                void move() override {
                    std::cout << "汽车在公路上行驶。" << std::endl;
                }
            };
            
            // 子类:飞机
            class Plane : public Vehicle {
            public:
                // 实现纯虚函数
                void move() override {
                    std::cout << "飞机在天空中飞行。" << std::endl;
                }
            };
            
            int main() {
                // Vehicle vehicle; // 错误,抽象类不能实例化
                Car car;
                Plane plane;
            
                car.move();
                plane.move();
            
                return 0;
            }
            

            代码解释

            • Vehicle 类是一个抽象类,因为它包含纯虚函数 moveCarPlane 类继承自 Vehicle 类,并实现了纯虚函数 move。由于 Vehicle 是抽象类,不能直接创建 Vehicle 类的对象,但可以创建其子类的对象。

            3. 总结

            面向对象编程通过封装、继承、多态和抽象等特性,让代码更加模块化、可复用和易于维护。在实际编程中,我们可以根据具体的需求,合理运用这些特性来设计和实现程序。希望通过这些示例和解释,你能对 C++ 的面向对象思想有更深入的理解。

            • 1