C++インターフェース完全理解:抽象クラスと純粋仮想関数
インターフェースとは、特定の実装にコミットすることなく、C++クラスの振る舞いや能力を記述するものです。
C++のインターフェースは 抽象クラス を使用して実装され、これらの抽象クラスを、関連データから実装詳細を分離する概念であるデータ抽象化と混同すべきではありません。
クラスの関数の少なくとも1つを 純粋仮想 関数として宣言することで、クラスを抽象クラスにします。純粋仮想関数は、宣言時に "= 0" を指定します:
class Box {
public:
// 純粋仮想関数
virtual double getVolume() = 0;
private:
double length; // 箱の長さ
double breadth; // 箱の幅
double height; // 箱の高さ
};
抽象クラス(しばしばABCと呼ばれる)の目的は、他のクラスが継承できる適切な基底クラスを提供することです。抽象クラスはオブジェクトのインスタンス化に使用できず、インターフェース としてのみ機能します。抽象クラスのオブジェクトをインスタンス化しようとすると、コンパイルエラーになります。
したがって、ABCのサブクラスをインスタンス化する必要がある場合、そのサブクラスはすべての仮想関数を実装しなければなりません。つまり、ABCで宣言されたインターフェースをサポートすることになります。派生クラスで純粋仮想関数をオーバーライドせずにそのクラスのオブジェクトをインスタンス化しようとすると、コンパイルエラーになります。
オブジェクトをインスタンス化するために使用できるクラスを 具象クラス と呼びます。
抽象クラスの例
親クラスが getArea() という関数を実装するためのインターフェースを基底クラスに提供する例を考えます:
Live Demo#include <iostream>
using namespace std;
// 基底クラス
class Shape {
public:
// インターフェースフレームワークを提供する純粋仮想関数
virtual int getArea() = 0;
void setWidth(int w) { width = w; }
void setHeight(int h) { height = h; }
protected:
int width;
int height;
};
// 派生クラス
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);
// オブジェクトの面積を出力
cout << "Total Rectangle area: " << Rect.getArea() << endl;
Tri.setWidth(5);
Tri.setHeight(7);
// オブジェクトの面積を出力
cout << "Total Triangle area: " << Tri.getArea() << endl;
return 0;
}
上記コードをコンパイルして実行すると、以下の結果が得られます:
Total Rectangle area: 35 Total Triangle area: 17
抽象クラスが getArea() というインターフェースを定義し、2つのクラスが同じ関数をそれぞれの形状に固有のアルゴリズムで実装していることがわかります。
設計戦略
オブジェクト指向システムでは、すべての外部アプリケーションに適した共通の標準化されたインターフェースを提供するために、抽象基底クラスを使用することがあります。その後、その抽象基底クラスからの継承を通じて、同様に動作する派生クラスが形成されます。
外部アプリケーションによって提供される能力(つまり、パブリック関数)は、抽象基底クラスで純粋仮想関数として提供されます。これらの純粋仮想関数の実装は、アプリケーションの特定のタイプに対応する派生クラスで提供されます。
このアーキテクチャにより、システムが定義された後でも、新しいアプリケーションをシステムに簡単に追加できるようになります。
C言語
- C++構造体とクラス:組み込み開発者のための実践ガイド
- C# 抽象クラスと抽象メソッドをマスターする:実践ガイド
- C++演算子完全ガイド:算術・代入・関係・論理・ビット演算子と実例
- C++クラスとオブジェクト完全ガイド:オブジェクト指向プログラミングの実践
- C++フレンド関数とフレンドクラス:アクセス制御のマスター
- C++クラステンプレート完全ガイド:実践的なジェネリックプログラミング
- C#抽象クラス実践チュートリアル:コード例で理解する設計パターン
- Java抽象クラスとメソッド:包括的ガイド
- Javaオブジェクトとクラス:コアOOP概念を完全理解
- Java抽象化完全ガイド: 抽象クラス・抽象メソッドで実装を隠蔽し設計を簡潔に
- Javaインターフェース完全ガイド: 定義・実装・多重継承・タグインターフェース