V信公众号: 程序员架构笔记
欢迎关注
C++ 面向对象编程(OOP) 封装、继承与多态 继承:单继承与多继承 虚函数与多态 抽象类与接口
C++ 是一种支持面向对象编程(OOP)的语言,其核心概念包括 封装、继承 和 多态。下面我们将详细讨论这些概念,并介绍 继承、虚函数与多态、抽象类与接口 的实现。
1. 封装、继承与多态
封装
封装是将数据(成员变量)和操作数据的方法(成员函数)捆绑在一起,并隐藏内部实现细节的过程。通过访问控制(public
、private
、protected
),可以限制对类成员的访问。
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++能够支持强大的面向对象编程范式,帮助开发者构建模块化、可扩展的软件系统。