Tutorial Study Image

C++ 中的接口(抽象类)


2023年6月16日, Learn eTutorial
992

我们将在本节讨论 C++ 接口。接口定义为:它解释了类的行为,而没有揭示该类的实现(代码)。

例如,在 ATM 机上,您将看到该银行提供的一系列选项,例如取款和存款,但看不到这些服务的后端代码实现。

  • 有时,只需向用户提供一系列接口选项形式的服务,而不是揭示项目的所有实现细节,就足够了。
  • 必要时,这种隐藏实现细节的行为被称为接口。

在 C++ 中,抽象是通过抽象类实现的。在 C++ 中,抽象是一种隐藏内部细节并仅显示功能的技巧。有两种方法可以实现抽象

  • 抽象类
  • 接口

抽象类和接口都能够拥有所需的抽象方法。

C++ 中的抽象类

在 C++ 中,通过声明其至少一个函数为纯虚函数来抽象一个类。在声明中,"= 0" 用于表示纯虚函数。它派生自的类必须提供其实现。让我们来看一个 C++ 中的抽象类,它有一个抽象方法 draw ()。派生类 Circle 和 Rectangle 提供它们的实现。这两个类使用不同的实现。

抽象类示例程序


#include <iostream>  
using namespace std;  
 class Shape    
{    
    public:   
    virtual void draw()=0;    
};    
 class Rectangle : Shape    
{    
    public:  
     void draw()    
    {    
        cout <<"drawing the rectangle..." <<endl;    
    }    
};    
class Circle : Shape    
{    
    public:  
     void draw()    
    {    
        cout <<"drawing the  circle..." <<endl;    
    }    
};    
int main( ) {  
    Rectangle rec;  
    Circle cir;  
    rec.draw();    
    cir.draw();   
   return 0;  
}  

 

输出


drawing the rectangle...
drawing the  circle...

设计策略

面向对象系统可以使用抽象基类来提供统一的通用接口,适用于所有外部应用程序。然后,通过继承该抽象基类,生成类似操作的派生类。

抽象基类以纯虚函数的形式提供外部应用程序提供的功能(即公共函数)。适用于各种应用程序类型的派生类提供这些纯虚函数的实现。

C++ 中的接口是什么意思?

C++ 类的行为或功能通过接口描述,而不对类的实现做任何假设。

区分数据抽象(即分离实现细节与相关数据的思想)和用于实现 C++ 接口的抽象类很重要。

当一个类的至少一个函数被声明为纯虚函数时,该类就成为抽象类。在函数声明中添加“= 0”表示它是一个纯虚函数。


class Box {
   public:
      // pure virtual function
      virtual double getVolume() = 0;
      
   private:
      double length;      // Length of a box
      double breadth;     // Breadth of a box
      double height;      // Height of a box
};
 

抽象类(通常称为 ABC)的作用是提供一个合适的基类,其他类可以从中继承。抽象类仅用作接口,不能用于创建对象。尝试实例化抽象类对象时会发生编译错误。

因此,为了支持 ABC 声明的接口,ABC 的子类在实例化之前必须实现每个虚函数。如果派生类中的纯虚函数在尝试实例化该类的对象之前未被覆盖,则会发生编译错误。

具体类是那些可以用于创建对象的类。

抽象类是其至少一个函数被声明为纯虚函数,并且纯虚函数必须声明为公共访问权限的类。抽象类用于实现语法接口。

语法


class class_name 
{
  public:
  // pure virtual function
  virtual return-type func_name() = 0;
};
 

定义纯虚函数时,在声明中使用 (=0)。

请看下面的示例,其中父类为子类提供了实现 getArea() 声明函数的接口。

C++ 程序显示接口的示例


#include <iostream>
 
using namespace std;
 
// Base class
class Shape {
   public:
      // pure virtual function just for providing interface framework.
      virtual int getArea() = 0;
      void setWidth(int w) {
         width = w;
      }
   
      void setHeight(int h) {
         height = h;
      }
   
   protected:
      int width;
      int height;
};
 
// Derived classes
class Rectangle: public Shape {
   public:
      int getArea() { 
         return (width * height); 
      }
};

class Triangle: public Shape {
   public:
      int getArea() { 
         return (width * height)/2; 
      }
};
 
int main(void) {
   Rectangle Rect;
   Triangle  Tri;
 
   Rect.setWidth(5);
   Rect.setHeight(7);
   
   // Print the area of the object.
   cout << "The Total Rectangle area: " << Rect.getArea() << endl;

   Tri.setWidth(5);
   Tri.setHeight(7);
   
   // Print the area of the object.
   cout << "The Total Triangle area: " << Tri.getArea() << endl; 

   return 0;
}


输出


The Total Rectangle area: 35
The Total Triangle area: 17

您可以看到两个其他类如何实现相同的函数,但使用各种算法来计算特定于形状的面积,而抽象类创建了一个 getArea() 形式的接口。

关于抽象类的注意事项

如果您尝试从抽象类构造对象,将会发生编译时错误,因为您不允许使用它,并且它只能用作接口。

唯一允许生成和使用对象的类是实现父抽象类的子类,并且该类必须定义父类的所有纯虚函数。

为什么要用接口?

OOP 设计系统中的抽象基类将提供一个单一的通用接口,该接口适用于所有相同类型的外部应用程序。

即使在软件系统开发完成后,接口机制也使得应用程序能够快速添加新的软件更新并对现有系统进行其他修改。