36項 インタフェースの継承と実装の継承とを区別しよう
インタフェースの継承と実装の継承とを区別しよう
・純粋仮想関数を宣言する目的は、派生クラスに関数のインタフェースを継承させることのみ。
・一般仮想関数を宣言する目的は、関数のインタフェースとデフォルトの実装を継承させること。
・非仮想関数を宣言する目的は、関数のインタフェースと強制的な実装を継承させること。
※一般仮想関数で、デフォルトの実装を継承するのは、危険な場合があります。
デフォルトの実装を分離させる時は、
1,インタフェースを純粋仮想関数で継承し、実装はprotectedな非仮想関数とする。
2,純粋仮想関数に実装を持たせる。
という2つの方法が挙げられています。
1の例は下のコードです。
class Airplane{ public: virtual void fly(const Airport &destination) = 0; protected: void defaultFly(const Airport &destination); }; void Airplane::defaultFly(const Airport &destination) { ... //飛行機を飛ばすためのデフォルトのコード } class ModelA : public Airplane { public: virtual void fly(const Airport &destination) { defaultFly(destination); //デフォルトの実装を呼び出す。 } }; class ModelB : public Airplane { public: virtual void fly(const Airport &destination) { ... //個別の実装を書く } };
2の例は下のコードです。
class Airplane{ public: virtual void fly(const Airport &destination) = 0; }; void Airplane::fly(const Airport &destination) { ... //飛行機を飛ばすためのデフォルトのコード } class ModelA : public Airplane { public: virtual void fly(const Airport &destination) { Airplane::fly(destination);//デフォルトのコードを呼び出す } }; class ModelB : public Airplane { public: virtual void fly(const Airport &destination) { ... //個別の実装を書く } };