• C++零基础教程(抽象类和接口)



    前言

    本篇文章来讲解抽象类和接口的概念,抽象类和接口都需要依靠我们之前讲解的虚函数来实现,那么我们就来看看如何使用虚函数来实现抽象类和接口吧。

    一、抽象类概念

    抽象类是一种不能直接实例化(即创建对象)的类,它被用作其他类的基类或接口。抽象类通过声明纯虚函数(没有具体实现的虚函数)来定义接口,而派生类必须实现这些纯虚函数才能被实例化。
    以下是抽象类的特点和用途:

    1.抽象类不能直接实例化:抽象类只能作为基类用于继承,并为派生类提供接口和共享的行为。由于抽象类中存在纯虚函数,没有为其提供具体实现,因此不能直接创建抽象类的对象。

    2.包含纯虚函数:抽象类中至少包含一个纯虚函数,通过在函数声明的末尾加上= 0来表示纯虚函数。纯虚函数没有具体的实现,派生类必须提供实现才能实例化。当一个类中有纯虚函数时,该类就成为抽象类。

    3.定义接口:抽象类定义了一组纯虚函数,用于声明派生类必须实现的操作。这些纯虚函数可以视为接口,规定了派生类的行为。

    4.提供默认实现:抽象类中可以包含非纯虚函数,它们可以有默认实现。这些非纯虚函数提供了通用行为或共享功能,派生类可以选择性地重写这些函数。

    5.强迫派生类实现纯虚函数:派生类必须实现基类中的纯虚函数,否则派生类也会被视为抽象类,无法实例化。

    6.支持多态性:通过继承抽象类并实现纯虚函数,派生类可以对基类的接口进行自定义实现,并以多态的方式使用这些派生类对象。

    抽象类提供了一种定义接口和约束派生类的机制,它是面向对象编程中的重要概念。通过使用抽象类,我们可以设计出具有共享接口的相似对象,并实现代码重用和扩展性。同时,抽象类也允许我们使用多态性来处理不同类型的对象,提高代码的灵活性和可维护性。

    二、抽象类例子

    当深入OOP(面向对象编程)时,抽象类的一个常见用例是定义一个通用的形状类,并通过派生类实现具体的形状(如矩形、圆形等)。下面是一个用C++实现的示例:

    #include 
    
    // 抽象类 Shape
    class Shape {
    public:
        virtual double getArea() const = 0; // 纯虚函数
        virtual double getPerimeter() const = 0; // 纯虚函数
        virtual void print() const = 0; // 纯虚函数
    };
    
    // 派生类 Rectangle
    class Rectangle : public Shape {
    private:
        double length;
        double width;
    
    public:
        Rectangle(double l, double w) : length(l), width(w) {}
    
        double getArea() const override {
            return length * width;
        }
    
        double getPerimeter() const override {
            return 2 * (length + width);
        }
    
        void print() const override {
            std::cout << "Rectangle: length = " << length << ", width = " << width << std::endl;
        }
    };
    
    // 派生类 Circle
    class Circle : public Shape {
    private:
        double radius;
    
    public:
        Circle(double r) : radius(r) {}
    
        double getArea() const override {
            return 3.14 * radius * radius;
        }
    
        double getPerimeter() const override {
            return 2 * 3.14 * radius;
        }
    
        void print() const override {
            std::cout << "Circle: radius = " << radius << std::endl;
        }
    };
    
    int main() {
        Rectangle rectangle(5, 3);
        Circle circle(2.5);
    
        Shape* shape1 = &rectangle; // 使用基类指针指向派生类对象
        Shape* shape2 = &circle;
    
        shape1->print(); // 多态调用
        std::cout << "Area: " << shape1->getArea() << ", Perimeter: " << shape1->getPerimeter() << std::endl;
    
        shape2->print();
        std::cout << "Area: " << shape2->getArea() << ", Perimeter: " << shape2->getPerimeter() << std::endl;
    
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68

    在上述代码中,定义了一个抽象类Shape,并声明了纯虚函数getArea()、getPerimeter()和print(),用于获取形状的面积、周长和打印形状信息。然后通过派生类Rectangle和Circle分别实现这些纯虚函数。

    在main()函数中,创建了具体的Rectangle和Circle对象,并使用基类指针Shape* 指向派生类对象。通过多态性,我们可以调用基类指针的函数来实现对派生类对象的操作。最后,使用多态特性打印并计算了各个形状的面积和周长。

    三、接口概念

    在面向对象编程中,接口是一种定义类行为的抽象规范。它定义了类应该具有的方法和属性,但没有提供具体的实现。接口只关注类提供的操作,而不关心其内部实现细节。

    以下是接口的特点和用途:

    1.纯虚函数:接口中的方法通常是纯虚函数(C++中的纯虚函数通过= 0表示),即没有具体实现的函数。接口声明了类必须实现的操作,但不指定具体的实现方式。

    2.定义行为规范:接口定义了一组方法,并规范了类应该具有的行为。它描述了一个类的功能,提供了对类的使用者的一种合约或承诺。

    3.多态性支持:通过实现接口,类可以具备多态性。多态允许使用基类指针或引用来引用派生类的对象,并在运行时调用相应的方法。

    4.实现解耦:接口可以将类的实现与其使用者分离,使得类和使用者之间只通过接口定义的方法进行通信。这样可以降低代码的耦合性,使系统更加灵活和可扩展。

    5.重用和扩展:接口允许类实现多个接口,从而在不同的上下文中使用相同的类。这样可以实现代码的重用并支持类的扩展。

    6.设计契约:接口可以被视为类与使用者之间的契约或协议。通过接口,类向外部世界公开一组操作,使用者通过接口来与类进行交互,而不需要关注其内部实现。

    四、接口和抽象类的区别

    接口和抽象类是面向对象编程中的两个重要概念,它们在某些方面有相似之处,但也存在一些关键区别。下面是接口和抽象类之间的主要区别:

    1.实现方式:接口(Interface)只能定义方法和常量,不能包含具体的实现代码,而抽象类(Abstract Class)可以包含方法的实现代码和属性等成员。

    2.继承关系:类通过实现接口来遵循接口定义的行为规范,一个类可以实现多个接口。而抽象类通过继承来扩展或修改其基类的行为。

    3.多重继承限制:一个类可以实现多个接口,因此可以具备不同接口的特性。然而,类只能继承一个抽象类,因为大多数编程语言不支持多重继承。

    4.构造函数:抽象类可以拥有构造函数,而接口不能具有构造函数。抽象类的构造函数主要用于在实例化时执行一些通用逻辑。

    5.默认实现:接口中的方法都是抽象的,没有默认实现。而抽象类可以包含抽象方法和非抽象方法,非抽象方法可以提供默认实现。

    6.设计层次:接口用于定义行为规范,将类的实现与使用者解耦。抽象类更倾向于在类的继承层次结构中扮演基类的角色,提供一些通用的行为和属性供子类继承和扩展。

    总结

    本篇文章就讲解到这里,下篇文章我们继续讲解。

  • 相关阅读:
    rr来debug你的C/C++程序(Linux)
    使用阿里云镜像加速pip命令的包安装
    Android学习笔记 70. 学会帮助自己【自理】
    SpringBoot 入门
    C++多态
    zotero插件推荐
    Android Studio的代码笔记--关于类的注释和函数的注释,以及USER值的修改。
    河南科技大学2023考研获取真题大纲的正规途径有哪些?
    物体6D位姿估计方法总结
    代码审计:python代码审计汇总(持续更新中)
  • 原文地址:https://blog.csdn.net/m0_49476241/article/details/131795621