OOPの特徴は継承によるコード再利用促進です。
新しいクラスは基本クラスと呼ばれる既存クラスから作られます。
派生クラスは基本クラスのメンバを使用するだけでなく、それらを変更・補完する事が出来ます。
多くの型は既存の型のバリエーションです。
それは多くの場合、各バリエーションの為に新しいコードを開発する事が面倒です。
また、新しいコードは新しいエラーを意味します。
派生クラスは基本クラスの記述を継承するので、ソースコードの再開発と再試験は不要です。
継承関係は階層構造になっています。
階層は全ての多様性と複雑な要素をコピーする事が出来ます。
これはオブジェクトの分類を取り入れます。
例えば、元素周期表はガスを持っています。
ガスは全ての全周期元素に固有の特性を保有しています。
不活性ガスは、次に重要なサブクラスを構成します。
The hierarchy is that the inert gas, such as argon is a gas, and gas, in its turn, is part of the system.
このような階層は不活性ガスの挙動を簡単に解釈出来ます。
他の全ての要素についても同様に原子には陽子と電子が含まれている事が分かります。
不活性ガスは全てのガスのように常温で気体状態である事が分かります。
不活性ガスのサブクラスから、通常他元素と化学反応を起こしにくい事が分かります。
これは全て不活性ガスの特性です。
幾何学的形状の継承の例を考えてみましょう。
様々な単純な形状(円形、三角形、長方形、正方形等)を記述する為の最善の方法は、全て派生クラスの元である基本クラス(ADT)を作成する事です。
形状を記述する最も一般的なメンバを含む基本クラスCShapeを作成してみましょう。
これらのメンバは形状の特徴であるプロパティ(形状の型やメインアンカーポイント座標)を記述します。
例:
class CShape {
protected :
int m_type;
int m_xpos;
int m_ypos;
public :
CShape(){m_type=0; m_xpos=0; m_ypos=0;}
void SetXPos(int x){ m_xpos=x; }
void SetYPos(int y){ m_ypos=y; }
};
クリップボードにコピー
次に基本クラスから派生した新しいクラスを作成し、必要なフィールドを追加し、それぞれ特定クラスを指定します。
円形には半径値を含むメンバを追加する必要があります。
正方形は側面値によって特徴付けられます。
したがって、基本クラスCShapeから継承された派生クラスは次のように宣言されます。
例:
class CCircle : public CShape {
private :
int m_radius;
public :
CCircle(){ m_type=1; }
};
クリップボードにコピー
正方形クラス宣言も似ています。
class CSquare : public CShape {
private :
int m_square_side;
public :
CSquare(){ m_type=2; }
};
クリップボードにコピー
オブジェクト作成時に基本クラスのコンストラクタが最初に呼び出される事に注意する必要があります。
その後派生クラスの
コンストラクタ が呼び出されます。
オブジェクトが最初に破棄された場合、派生クラスの
デストラクタ が呼び出され、その後に基本クラスのデストラクタが呼び出されます。
このように、基本クラスの中で一般的なメンバを宣言する事によって、特定のクラスを指定して派生クラスにメンバを追加する事が出来ます。
継承は何度も再利用する事が出来る強力なコードライブラリを作成する事が出来ます。
既存のものから派生クラスを作成する為の構文は次の通りです。
継承の構文
class 派生クラス名 : (public | protected | private のいずれか) 基本クラス名 {
クラスメンバの宣言
};
クリップボードにコピー
派生クラスの側面の一つは、そのメンバの後継者の可視性です。
public,protected,privateキーワードはどの程度使用可能かを示すもので、基本クラスのメンバが派生クラスの為に利用します。
派生クラスヘッダのコロンの後にpublicキーワードを書いた場合、ベースクラスCShapeのprotectedとpublicメンバは、派生クラスCCircleのprotectedとpublicメンバとして継承される必要がある事を示します。
基本クラスのprivateメンバは派生クラスでは使用出来ません。
public継承は派生クラス(CCircleとCSquare)がCShapesである事を意味します。
CSquareは形状(CShape)ですが、形状は必ずしも正方形である必要はありません。
派生クラスは基本クラスの変形例で、これは基本クラスのprotectedとpublicメンバを継承します。
基本クラスのコンストラクタとデストラクタは継承出来ません。
基本クラスのメンバに加えて派生クラスに新しいメンバが追加されます。
派生クラスは、基本クラスとは違うメンバ関数の実装を含む事が出来ます。
これは
オーバーロード とは違い、同じ関数名の意味が異なるシグネチャの為異なっていても良いのです。
protected継承は、基本クラスのpublicとprotectedメンバは派生クラスのprotectedメンバになります。
pribate継承は、基本クラスのpublicとprotectedメンバは派生クラスのprivateメンバになります。
protectedとprivate継承は、「派生クラスのオブジェクトは基本クラスのオブジェクトである」という関係ではありません。
protectedとprivate継承はまれであり、慎重に使用する必要があります。
継承のタイプ(public,protected,private)は派生クラスが基本クラスメンバにアクセスする方法に影響を及ぼさない事を理解するべきです。
継承のいずれかのタイプでは、基本クラスでpublicとprotectedのアクセス指定が宣言されたメンバのみが派生クラスで利用出来ます。
次の例でそれを考えてみましょう。
class CBaseClass {
private :
int m_member;
protected :
int Member(){ return ( m_member ); }
public :
CBaseClass(){ m_member=5; return ; };
private :
void Member(int value) { m_member=value;};
};
class CDerived: public CBaseClass {
public :
void Func() {
m_member = 0;
Member(0);
Print (m_member);
Print (Member());
}
};
クリップボードにコピー
上記の例では、CBaseClassは唯一のpublicメソッドがコンストラクタです。
コンストラクタはクラスオブジェクトを作成する時に自動的に呼び出されます。
privateメンバm_memberとprotectedメソッドMember()は外から呼び出す事が出来ません。
しかしpublic継承の場合は、基本クラスのMember()メソッドは派生クラスから利用出来るようになります。
protected継承の場合は、基本クラスのpublicとprotectedメンバは全て派生クラスのprotectedメンバになります。
もし基本クラスのpublicデータメンバとpublicメソッドが外からアクセスする場合、protected継承では派生クラスまたは派生クラスの派生クラスからのみ利用可能を意味します。
class CBaseMathClass {
private :
double m_Pi;
public :
void SetPI(double v){ m_Pi=v; return ; };
double GetPI() { return m_Pi; };
public :
CBaseMathClass() { SetPI(3.14); PrintFormat ("%s" ,__FUNCTION__ ); };
};
class CProtectedChildClass: protected CBaseMathClass {
private :
double m_radius;
public :
void SetRadius(double r){ m_radius = r; return ; };
double GetCircleLength() { return GetPI() * m_radius;};
};
void OnStart() {
CProtectedChildClass pt;
pt.SetRadius(10);
PrintFormat ( "長さ = %G" ,pt.GetCircleLength());
CBaseMathClass bc;
bc.SetPI(10);
PrintFormat ( "bc.GetPI() = %G " ,bc.GetPI());
}
クリップボードにコピー
この例では、基本クラスCBaseMathClassのSetPI()とGetPi()メソッドがプログラムの任意の場所から呼び出せる事を示しています。
しかし同時に、派生するCProtectedChildClassでは、これらのメソッドはCProtectedChildClassクラスまたはその派生クラスからのみ呼び出せます。
private継承の場合は、基本クラスのpublicとprotectedの全メンバは派生クラスのpribateになり、派生クラスから呼び出せません。
MQL4は多重継承を持っていません。