継承とは何か?
特定のクラスの内容を別のクラスに引き継ぎ、前のメンバーの変数や関数を流用し、更に
新しく足したり修正したりすることを継承といいます。
このように、似たようなクラスを作成するのに何度も同じクラスを宣言する必要がありません。
新しいクラス元になるクラスを基本クラスといい、基本クラスから継承されたクラスを派生クラスといいます。
継承される前のメンバーも、新しいクラスで宣言したメンバーで上書きすることが出来ます。
派生クラスの宣言方法は以下の通りです。
class 派生クラス名:基本クラス名{
・・・
};
派生クラス前のクラスが例えば以下の通りです。
class Test1{
private:
//プライベートメンバー変数を設定する
int time1;
public:
//パブリックなメンバー変数を宣言する
int num1;
//パブリックなメンバー関数を設定する
void show_time1();
};
派生クラス後のクラスが例えば以下の通りです。
class Test2 : Test1{
private:
//プライベートメンバー変数を設定する
int time2;
public:
//パブリックなメンバー変数を宣言する
int num2;
//パブリックなメンバー関数を設定する
void show_time2();
};
ここでTest1から継承するときには:で区切りますが、Test1をpublicで継承するのか、それとも
privateで区切るのかを決めることが出来ます。
publicで区切れば、Test1の中身をTest2のインスタンスからTest1のpublicのメンバー変数・関数を利用することが出来ますが、
privateで宣言するとTest1で例えpublicでメンバー変数が宣言されていてもTest2のインスタンスからはTest1のメンバー変数を
利用することが出来ません。
しかし、Test2内のクラスからではTest1のpublicのメンバー変数・関数を利用することが出来ます。その内容を下記のプログラムで
表現しました。
#include <iostream>
#include <string>
using namespace std;
//クラスCarを設定する
class Test1{
private:
//プライベートメンバー変数を設定する
int time1;
public:
//パブリックなメンバー変数を宣言する
int num1;
//パブリックなメンバー関数を設定する
void show_time1();
};
//クラスTest1を基本クラスとして派生クラスTest2を宣言する
//publicを省略するとprivateになり、Test1の内容を外部から利用できなくなる
class Test2 : Test1{
private:
//プライベートメンバー変数を設定する
int time2;
public:
//パブリックなメンバー変数を宣言する
int num2;
//パブリックなメンバー関数を設定する
void show_time2();
};
//クラスTest1のメンバー関数time1の設定
void Test1::show_time1(){
cout << "現在の時刻は10時です" << endl;
}
//クラスTest2のメンバー関数time1の設定
void Test2::show_time2(){
cout << "現在の時刻は23時です" << endl;
show_time1();
}
int main(){
Test2 hoge;
hoge.show_time2();
//show_time1を利用するためにはTest1をpublicで継承しなければならない
//hoge.show_time1();
getchar();
}
実行結果は以下の通りです。
現在の時刻は23時です
現在の時刻は10時です
上記は、Test1をprivateで継承していますので、クラスTest2のインスタンスはTest1のメンバー変数を継承しても
直接show_time1等のTest1を利用することが出来ません。
しかし、Test2内の関数からではTest1のpublicのメンバー変数・関数を利用することが出来ます。
また、Test2内からTest1のprivateで宣言されている内容を利用したいことも生じます。
この為、protectedを利用すると、クラス外からは利用できませんが、クラスのメンバー関数からは利用できるようになります。
#include <iostream>
#include <string>
using namespace std;
//クラスCarを設定する
class Test1{
protected:
//プライベートメンバー変数を設定する
int time1;
public:
//パブリックなメンバー変数を宣言する
int num1;
//パブリックなメンバー関数を設定する
void show_time1();
};
//クラスTest1を基本クラスとして派生クラスTest2を宣言する
//publicを省略するとprivateになり、Test1の内容を外部から利用できなくなる
class Test2 : Test1{
private:
//プライベートメンバー変数を設定する
int time2;
public:
//パブリックなメンバー変数を宣言する
int num2;
//パブリックなメンバー関数を設定する
void show_time2();
};
//クラスTest1のメンバー関数time1の設定
void Test1::show_time1(){
cout << "現在の時刻は10時です" << endl;
}
//クラスTest2のメンバー関数time1の設定
void Test2::show_time2(){
cout << "現在の時刻は23時です" << endl;
show_time1();
time1 = 1;
cout << "メンバー変数time1の値は" << time1 << "です。" <<endl;
}
int main(){
Test2 hoge;
hoge.show_time2();
//show_time1を利用するためにはTest1をpublicで継承しなければならない
//hoge.show_time1();
getchar();
}
実行結果は以下の通りです。
現在の時刻は23時です
現在の時刻は10時です
メンバー変数time1の値は1です。
それでは、様々な型が出来ましたので纏めてみましょう。
関数のオーバーライド
関数のオーバーライドとは、派生クラス内で基本クラスのメンバー関数を上書きすることが出来ます。
しかし、引数の型が基本クラスと異なると別のメンバー関数としてみなされます。
//下記は異なるメンバー関数となります
void func::test(int a){
cout << "test1" << endl;
}
void func2::test(int a,int b){
cout << "test2" << endl;
}
//下記はメンバー関数のオーバーライドとなっています
void func::test1(int a){
cout << "test3" << endl;
}
void func2::test1(int a){
cout << "test4" << endl;
}
関数のオーバーライドをしてしまった場合でも、継承したオブジェクトはオーバーライド前の関数を利用することが可能です。
例えば、クラスfunc1のオブジェクトhogeは、func1のtest1を利用したいときはhoge.test1(引数)を実行します。
クラスfunc2のオブジェクトhogehogeはhogehoge.test1(引数)となります。
また、クラスfunc2からでもfunc1のtest1を呼び出すことが出来ます。
その場合は、スコープ解決演算子を付けます。
//下記は異なるメンバー関数となります
void func::test(int a){
cout << "test1" << endl;
}
void func2::test(int a,int b){
func::test(int a);//funcの基本クラスを利用可能です。
cout << "test2" << endl;
}
それでは実際にサンプルプログラムから見てみましょう!