Bootstrap

08 C++面向对象编程(OOP)封装、继承 和 多态详解

 V信公众号:  程序员架构笔记

欢迎关注

C++ 面向对象编程(OOP) 封装、继承与多态 继承:单继承与多继承 虚函数与多态 抽象类与接口

C++ 是一种支持面向对象编程(OOP)的语言,其核心概念包括 封装继承 和 多态。下面我们将详细讨论这些概念,并介绍 继承虚函数与多态抽象类与接口 的实现。


1. 封装、继承与多态

封装

封装是将数据(成员变量)和操作数据的方法(成员函数)捆绑在一起,并隐藏内部实现细节的过程。通过访问控制(publicprivateprotected),可以限制对类成员的访问。

class Person {
private:
    std::string name; // 私有成员,外部无法直接访问
    int age;

public:
    void setName(const std::string& n) { name = n; } // 公有方法,外部可以访问
    void setAge(int a) { age = a; }
    void display() {
        std::cout << "Name: " << name << ", Age: " << age << std::endl;
    }
};

继承

继承是从一个已有的类派生出新类的过程。派生类(子类)可以继承基类(父类)的成员,并可以添加新的成员或重写基类的成员函数。

  • 单继承:一个类只能继承一个基类。

  • 多继承:一个类可以继承多个基类。

单继承示例
#include <iostream>
#include <string>

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

// 派生类
class Dog : public Animal {
public:
    void bark() {
        std::cout << "Dog is barking." << std::endl;
    }
};

int main() {
    Dog dog;
    dog.eat();  // 继承自基类
    dog.bark(); // 派生类自己的方法
    return 0;
}
多继承示例
#include <iostream>
#include <string>

// 基类1
class Animal {
public:
    void eat() {
        std::cout << "Animal is eating." << std::endl;
    }
};

// 基类2
class Pet {
public:
    void play() {
        std::cout << "Pet is playing." << std::endl;
    }
};

// 派生类(多继承)
class Dog : public Animal, public Pet {
public:
    void bark() {
        std::cout << "Dog is barking." << std::endl;
    }
};

int main() {
    Dog dog;
    dog.eat();  // 继承自 Animal
    dog.play(); // 继承自 Pet
    dog.bark(); // 派生类自己的方法
    return 0;
}

多态

多态是指通过基类的指针或引用调用派生类的重写函数。多态的实现依赖于 虚函数


2. 虚函数与多态

虚函数

虚函数是在基类中使用 virtual 关键字声明的函数,允许在派生类中重写。通过基类指针或引用调用虚函数时,实际调用的是派生类的重写函数。

#include <iostream>
#include <string>

// 基类
class Animal {
public:
    virtual void makeSound() { // 虚函数
        std::cout << "Animal makes a sound." << std::endl;
    }
};

// 派生类
class Dog : public Animal {
public:
    void makeSound() override { // 重写虚函数
        std::cout << "Dog barks." << std::endl;
    }
};

// 派生类
class Cat : public Animal {
public:
    void makeSound() override { // 重写虚函数
        std::cout << "Cat meows." << std::endl;
    }
};

int main() {
    Animal* animal1 = new Dog();
    Animal* animal2 = new Cat();

    animal1->makeSound(); // 输出: Dog barks.
    animal2->makeSound(); // 输出: Cat meows.

    delete animal1;
    delete animal2;
    return 0;
}

多态的实现

多态的核心是通过基类指针或引用调用派生类的重写函数。虚函数表(vtable)是实现多态的底层机制。


3. 抽象类与接口

抽象类

抽象类是包含至少一个 纯虚函数 的类,不能实例化。纯虚函数通过在函数声明后加上 = 0 来定义。

#include <iostream>
#include <string>

// 抽象类
class Shape {
public:
    virtual void draw() = 0; // 纯虚函数
};

// 派生类
class Circle : public Shape {
public:
    void draw() override {
        std::cout << "Drawing a circle." << std::endl;
    }
};

// 派生类
class Square : public Shape {
public:
    void draw() override {
        std::cout << "Drawing a square." << std::endl;
    }
};

int main() {
    // Shape shape; // 错误:不能实例化抽象类
    Shape* shape1 = new Circle();
    Shape* shape2 = new Square();

    shape1->draw(); // 输出: Drawing a circle.
    shape2->draw(); // 输出: Drawing a square.

    delete shape1;
    delete shape2;
    return 0;
}

接口

在C++中,接口是通过纯虚函数实现的抽象类。接口只定义方法,不提供实现。

#include <iostream>
#include <string>

// 接口
class Drawable {
public:
    virtual void draw() = 0; // 纯虚函数
};

// 实现接口的类
class Circle : public Drawable {
public:
    void draw() override {
        std::cout << "Drawing a circle." << std::endl;
    }
};

// 实现接口的类
class Square : public Drawable {
public:
    void draw() override {
        std::cout << "Drawing a square." << std::endl;
    }
};

int main() {
    Drawable* drawable1 = new Circle();
    Drawable* drawable2 = new Square();

    drawable1->draw(); // 输出: Drawing a circle.
    drawable2->draw(); // 输出: Drawing a square.

    delete drawable1;
    delete drawable2;
    return 0;
}

总结

  • 封装:通过访问控制隐藏实现细节。

  • 继承:单继承和多继承,派生类可以继承基类的成员。

  • 多态:通过虚函数实现基类指针调用派生类的重写函数。

  • 抽象类:包含纯虚函数的类,不能实例化。

  • 接口:通过纯虚函数实现的抽象类,只定义方法。

这些特性使得C++能够支持强大的面向对象编程范式,帮助开发者构建模块化、可扩展的软件系统。

;