Учебники

Интерфейсы в 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. Неспособность переопределить чисто виртуальную функцию в производном классе, а затем попытаться создать экземпляр объекта этого класса, является ошибкой компиляции.

Классы, которые можно использовать для создания объектов, называются конкретными классами .

Пример абстрактного класса

Рассмотрим следующий пример, где родительский класс предоставляет интерфейс к базовому классу для реализации функции с именем getArea ()

Live Demo

#include <iostream>
 
using namespace std;
 
// Base class
class Shape {
   public:
      // pure virtual function 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 << "Total Rectangle area: " << Rect.getArea() << endl;

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

   return 0;
}

Когда приведенный выше код компилируется и выполняется, он дает следующий результат –

Total Rectangle area: 35
Total Triangle area: 17

Вы можете увидеть, как абстрактный класс определил интерфейс в терминах getArea (), и два других класса реализовали одну и ту же функцию, но с другим алгоритмом для вычисления области, специфичной для фигуры.

Разработка стратегии

Объектно-ориентированная система может использовать абстрактный базовый класс для обеспечения общего и стандартизированного интерфейса, подходящего для всех внешних приложений. Затем посредством наследования от этого абстрактного базового класса формируются производные классы, которые работают аналогично.

Возможности (то есть общедоступные функции), предлагаемые внешними приложениями, предоставляются как чисто виртуальные функции в абстрактном базовом классе. Реализации этих чисто виртуальных функций предоставляются в производных классах, которые соответствуют конкретным типам приложения.

Эта архитектура также позволяет легко добавлять новые приложения в систему даже после ее определения.