「C++系列」 接口(抽象类)

发布于:2024-09-18 ⋅ 阅读:(8) ⋅ 点赞:(0)

人工智能教程】,前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。

点击跳转到网站:【人工智能教程

一、接口(抽象类)

在C++中,接口的概念通常是通过抽象类来实现的。虽然C++标准中没有直接称为“接口”的关键字或特定类型,但抽象类可以被视为一种接口的实现方式。抽象类是一个不能被实例化的类,它通常包含至少一个纯虚函数(Pure Virtual Function)。纯虚函数是一个在基类中被声明但没有具体实现的函数,其目的是为了在派生类中实现该函数的具体版本。

1. 抽象类的定义

抽象类在C++中是通过包含至少一个纯虚函数的类来定义的。纯虚函数是通过在函数声明的末尾添加= 0来声明的。例如:

class IInterface {
public:
    // 纯虚函数
    virtual void pureVirtualFunction() = 0;

    // 也可以有实现的虚函数(可选)
    virtual void virtualFunction() {
        // 实现体
        std::cout << "IInterface::virtualFunction()" << std::endl;
    }

    // 也可以有非虚函数(可选)
    void nonVirtualFunction() {
        // 实现体
        std::cout << "IInterface::nonVirtualFunction()" << std::endl;
    }

    // 构造函数和析构函数(可选)
    IInterface() {}
    virtual ~IInterface() {}
};

2. 抽象类的使用

抽象类不能直接被实例化,即你不能直接创建IInterface类型的对象。但是,你可以创建从抽象类派生的具体类(即实现了所有纯虚函数的类),然后创建这些派生类的实例。

class ConcreteClass : public IInterface {
public:
    // 必须实现纯虚函数
    void pureVirtualFunction() override {
        std::cout << "ConcreteClass::pureVirtualFunction()" << std::endl;
    }

    // 可以选择性地覆盖非纯虚函数(可选)
    void virtualFunction() override {
        std::cout << "ConcreteClass::virtualFunction()" << std::endl;
    }

    // 也可以添加自己的成员函数(可选)
    void myFunction() {
        std::cout << "ConcreteClass::myFunction()" << std::endl;
    }
};

int main() {
    // 不能这样做:IInterface* obj = new IInterface(); // 错误:IInterface 是抽象类

    // 可以这样做:
    IInterface* obj = new ConcreteClass();
    obj->pureVirtualFunction(); // 调用 ConcreteClass 的实现
    obj->virtualFunction();     // 调用 ConcreteClass 的覆盖实现或 IInterface 的实现(如果未覆盖)
    obj->nonVirtualFunction();  // 调用 IInterface 的实现

    delete obj;
    return 0;
}

3. 接口的作用

接口(通过抽象类实现)在C++中的作用主要包括:

  1. 定义契约:接口为派生类定义了一个必须遵守的契约,即派生类必须实现接口中声明的所有纯虚函数。
  2. 促进多态:通过接口,可以实现多态性,即允许使用基类的指针或引用来指向派生类的对象,并通过这些指针或引用来调用虚函数(包括纯虚函数和非纯虚函数)的派生类版本。
  3. 解耦:接口有助于降低模块之间的耦合度,因为模块之间的交互是通过接口进行的,而不是直接通过具体的实现类进行的。这使得系统更加灵活和可扩展。
  4. 实现隐藏:接口隐藏了派生类的具体实现细节,只暴露了必要的接口供外部使用。这有助于保护系统的内部结构和数据不受外部干扰。

二、抽象类运用

C++中通过抽象类实现接口的概念是一种常用的设计模式,它允许我们定义一组方法(即纯虚函数),这些方法在继承自该抽象类的具体类中必须被实现。这种模式促进了代码的解耦、提高了系统的可扩展性和可维护性。

下面是一个C++接口(抽象类)运用及案例代码的示例:

1. 抽象类(接口)定义

首先,我们定义一个抽象类Shape,它包含了一个纯虚函数draw(),表示绘图的功能。这个类不能被实例化,因为它至少有一个纯虚函数。

#include <iostream>

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

    // 虚析构函数(可选,但推荐)
    virtual ~Shape() {}
};

2. 具体类实现

然后,我们定义几个具体类,如CircleRectangle,它们继承自Shape类并实现了draw()方法。

// Circle类,继承自Shape
class Circle : public Shape {
private:
    double radius;

public:
    Circle(double r) : radius(r) {}

    // 实现draw()方法
    void draw() const override {
        std::cout << "Drawing Circle with radius " << radius << std::endl;
    }
};

// Rectangle类,继承自Shape
class Rectangle : public Shape {
private:
    double width, height;

public:
    Rectangle(double w, double h) : width(w), height(h) {}

    // 实现draw()方法
    void draw() const override {
        std::cout << "Drawing Rectangle with width " << width << " and height " << height << std::endl;
    }
};

3. 客户端代码

最后,我们在客户端代码中创建CircleRectangle的对象,并通过Shape类型的指针来调用它们的draw()方法,展示多态性的使用。

int main() {
    // 创建Circle和Rectangle对象
    Circle c(5.0);
    Rectangle r(4.0, 6.0);

    // 通过Shape类型的指针调用draw()方法
    Shape* shapePtr;

    shapePtr = &c;
    shapePtr->draw(); // 输出:Drawing Circle with radius 5

    shapePtr = &r;
    shapePtr->draw(); // 输出:Drawing Rectangle with width 4 and height 6

    return 0;
}

在这里插入图片描述

三、相关链接

  1. Visual Studio Code下载地址
  2. Sublime Text下载地址
  3. 「C++系列」C++简介、应用领域
  4. 「C++系列」C++ 基本语法
  5. 「C++系列」C++ 数据类型
  6. 「C++系列」C++ 变量类型
  7. 「C++系列」C++ 变量作用域
  8. 「C++系列」C++ 常量知识点-细致讲解
  9. 「C++系列」C++ 修饰符类型
  10. 「C++系列」一篇文章说透【存储类】
  11. 「C++系列」一篇文章讲透【运算符】
  12. 「C++系列」循环
  13. 「C++系列」判断
  14. 「C++系列」函数/内置函数
  15. 「C++系列」数字/随机数
  16. 「C++系列」数组
  17. 「C++系列」字符串
  18. 「C++系列」指针
  19. 「C++系列」引用
  20. 「C++系列」日期/时间
  21. 「C++系列」输入/输出
  22. 「C++系列」数据结构
  23. 「C++系列」vector 容器
  24. 「C++系列」类/对象
  25. 「C++系列」继承
  26. 「C++系列」重载运算符/重载函数
  27. 「C++系列」多态
  28. 「C++系列」数据抽象
  29. 「C++系列」数据封装