解答編 アクセス指定子private,public,protectedを用いてクラスの継承を行った場合 どのように親クラスのメンバ変数宣言、メンバ関数宣言は子クラスに引き継がれるのでしょうか?

解答編 アクセス指定子private,public,protectedを用いてクラスの継承を行った場合 どのように親クラスのメンバ変数宣言、メンバ関数宣言は子クラスに引き継がれるのでしょうか?

ソーラー「


親クラスGameCharacter

から

子クラスDragon へ



クラスの継承を


アクセス指定子protected

アクセス指定子public

アクセス指定子private


を用いて


class Dragon:protected GameCharacter

class Dragon:public GameCharacter

class Dragon:private GameCharacter

のように



実行したとき


どのようなことがおこるか?


そのことが



非常によくわかる


プログラムを用意してみたんだ(´▽`*)


まずは


1つ目のプログラムをご覧ください。


マックス「おお、なんか自信がありそうだな(*´▽`*)」


#include <iostream>

#include <string>//文字列を取り扱うためにヘッダファイル <string>をインクルードしています

using namespace std;


//👇🌞🌞🌞クラスGameCharacterです🌞🌞🌞

class GameCharacter {


public:

string name;

int HP;

int MP;


void statusDataDisplay();



};



void GameCharacter::statusDataDisplay() {


cout << name << "\n";

cout << "HP " << HP << "\n";

cout << "MP " << MP << "\n";

}





//👇🌞🌞🌞クラスGameCharacterを継承したクラスDragonです🌞🌞🌞


class Dragon :protected GameCharacter {

public:

void statusDataDisplay2(string a, int b, int c);


};


//👇🌞🌞🌞クラスDragonのメンバ関数statusDataDisplay2(string a, int b, int c)の定義です🌞🌞🌞

void Dragon::statusDataDisplay2(string a, int b, int c) {


name = a;

HP = b;

MP = c;


cout << name << "\n";

cout << "HP " << HP << "\n";

cout << "MP " << MP << "\n";

}


int main() {


Dragon Pokky;


Pokky.statusDataDisplay2("ポッキー", 15, 5);


return 0;

}


プログラムの実行結果


ポッキー

HP 15

MP 5


マックス「なんだ(笑)


親クラスGameCharacter

から

子クラスDragon へ


クラスの継承をアクセス指定子protectedを用いて


実行しているのにプログラムが実行できとるぅぅ


なあアんでだぁ?


今まで無理っぽかったのにィ


さっきのエピソードではビルドエラーが表示されたのにぃ」



ソーラー「😊それもそのはず😊


もともと


親クラスGameCharacter

から

子クラスDragon へ


クラスの継承をアクセス指定子protectedを用いて行っても


ちゃんと


プログラムを実行することができるようシステムが設計されているからです


このプログラムのmain関数内では


Pokky.name

Pokky.HP

Pokky.MP

が用いられていませんね


Pokky.name

Pokky.HP

Pokky.MP

には



子クラスDragon型のオブジェクトPokkyのメンバ関数を用いてのみ


アクセスできるようになります」


マックス「?」


ソーラー「


つまり


🌞🌞🌞親クラスのクラス宣言が🌞🌞🌞

👇

class GameCharacter {


public:

string name;

int HP;

int MP;


void statusDataDisplay();


};

👆

のように設定されていて


親クラスGameCharacter

から

子クラスDragon へ


クラスの継承をアクセス指定子protectedを用いて行ったとします


その際



🌞🌞🌞クラスGameCharacterを継承した子クラスDragonのクラス宣言🌞🌞🌞は以下のようになります

👇

class Dragon:protected GameCharacter {

public:

void statusDataDisplay2(string a, int b, int c);


};



このクラスGameCharacterを継承した子クラスDragonのクラス宣言内には

見えていないだけで


親クラスGameCharacterのメンバ変数宣言

string name;

int HP;

int MP;


親クラスGameCharacterのメンバ関数宣言


void statusDataDisplay();


が引き継がれています


例えば


次のような感じです

👇

class Dragon:protected GameCharacter {


protected://🌞🌞🌞アクセス指定子protectedが設定されていることに大注目🌞🌞🌞

string name;

int HP;

int MP;


void statusDataDisplay();


public:

void statusDataDisplay2(string a, int b, int c);


};


マックス「な、なんとお


親クラスGameCharacter

から

子クラスDragon へ


クラスの継承を


    🌞🌞アクセス指定子protectedを用いて行った場合🌞🌞


👇


アクセス指定子がpublicに設定されている


親クラスGameCharacterのメンバ変数宣言

string name;

int HP;

int MP;


親クラスGameCharacterのメンバ関数宣言


void statusDataDisplay();

👆




      🌞🌞アクセス指定子protected🌞🌞


が付けられた状態の

👇

protected://🌞🌞🌞アクセス指定子protectedが設定されていることに大注目🌞🌞🌞

string name;

int HP;

int MP;


void statusDataDisplay();

👆

として


子クラスに引き継がれるのか!!?


ってもうわかっとるわ~


何回目だ!!?」


ソーラー「!そうなんです


同様に


親クラスGameCharacter

から

子クラスDragon へ


クラスの継承を


    🌞🌞アクセス指定子publicを用いて行った場合🌞🌞

👇


アクセス指定子がpublicが設定された


親クラスGameCharacterのメンバ変数宣言

string name;

int HP;

int MP;


親クラスGameCharacterのメンバ関数宣言


void statusDataDisplay();

👆




      🌞🌞アクセス指定子public🌞🌞


が付けられた状態の

👇

public:

//👆🌞🌞🌞アクセス指定子publicが設定されていることに大注目🌞🌞🌞

string name;

int HP;

int MP;


void statusDataDisplay();

👆

として


子クラスDragon に引き継がれます


そうですね


親クラスGameCharacter

から

子クラスDragon へ


クラスの継承を


    🌞🌞アクセス指定子publicを用いて行った場合🌞🌞



🌞🌞🌞クラスGameCharacterを継承した子クラスDragonのクラス宣言🌞🌞🌞は

            

                ふつう


以下のようになります

👇

class Dragon:public GameCharacter {

public:

void statusDataDisplay2(string a, int b, int c);


};


👆


この親クラスGameCharacterを継承した



子クラスDragonのクラス宣言内には



見えていないだけで


親クラスGameCharacterのメンバ変数宣言

string name;

int HP;

int MP;


親クラスGameCharacterのメンバ関数宣言


void statusDataDisplay();


が引き継がれています


例えば


次のような感じです


class Dragon :public GameCharacter {


public://🌞🌞🌞アクセス指定子publicが設定されていることに大注目🌞🌞🌞

string name;

int HP;

int MP;


void statusDataDisplay();


public:

void statusDataDisplay2(string a, int b, int c);


};

(👆こんな感じです)


マックス「OH~~~ぅ しびれるぅ」


ソーラー「さらに


同様に


親クラスGameCharacter

から

子クラスDragon へ


クラスの継承を


    🌞🌞アクセス指定子privateを用いて行った場合🌞🌞

👇


アクセス指定子がpublicに設定された


親クラスGameCharacterのメンバ変数宣言

string name;

int HP;

int MP;


親クラスGameCharacterのメンバ関数宣言


void statusDataDisplay();

👆




      🌞🌞アクセス指定子private🌞🌞


が付けられた状態の

👇

private://🌞🌞🌞アクセス指定子privateが設定されていることに大注目🌞🌞🌞

string name;

int HP;

int MP;


void statusDataDisplay();

👆

として


子クラスDragon に引き継がれます


親クラスGameCharacter

から

子クラスDragon へ


クラスの継承を


    🌞🌞アクセス指定子privateを用いて行った場合🌞🌞



               ふつう



🌞🌞🌞クラスGameCharacterを継承した子クラスDragonのクラス宣言🌞🌞🌞は以下のようになりますね

👇

class Dragon:public GameCharacter {

public:

void statusDataDisplay2(string a, int b, int c);


};


👆


この親クラスGameCharacterを継承した子クラスDragonのクラス宣言内には見えていないだけで


親クラスGameCharacterのメンバ変数宣言


string name;

int HP;

int MP;


親クラスGameCharacterのメンバ関数宣言


void statusDataDisplay();


が引き継がれています


例えば


次のような感じです


class Dragon:private GameCharacter {


private://🌞🌞🌞アクセス指定子privateが設定されていることに大注目🌞🌞🌞

string name;

int HP;

int MP;


void statusDataDisplay();


public:

void statusDataDisplay2(string a, int b, int c);


};


マックス「OH~~~ぅ  うぅぅ~」



てんC「ソーラーさん 大発見ですね!」



ソーラー「ですので


親クラスGameCharacter

から

子クラスDragon へ


クラスの継承を


    🌞🌞アクセス指定子privateを用いて行った場合🌞🌞


子クラスDragonのクラス宣言は

👇

class Dragon:private GameCharacter {


private://🌞🌞🌞アクセス指定子privateが設定されていることに大注目🌞🌞🌞

string name;

int HP;

int MP;


void statusDataDisplay();


public:

void statusDataDisplay2(string a, int b, int c);


};

👆

のように設定されていることになりますが


string name;

int HP;

int MP;


void statusDataDisplay();


のアクセス指定子が


private


に設定されていることになるので


Pokkyの子クラスDragon💖💖💖💖💖💖型のオブジェクト宣言


Dragon Pokky;


を実行して


子クラスDragon型のオブジェクトPokkyを作製しても


親クラスGameCharacterのメンバ変数


name

HP

MP

が用いられた


子クラスDragon型のオブジェクトPokkyのメンバ変数


Pokky.name

Pokky.HP

Pokky.MP


を使用することはできません


ですので


子クラスDragon型のオブジェクトPokkyのメンバ変数


Pokky.name

Pokky.HP

Pokky.MP



を使用して


          🍎🐤直接🍎🐤



Pokky.name = "ポッキー";

Pokky.HP = 15;

Pokky.MP = 5;


のようにデータを代入することはできません




         そうなんです 気づいた方もおられると思います



             カプセル化が



行われているのです


この場合


親クラスGameCharacterのメンバ関数宣言


void statusDataDisplay();


のアクセス指定子が


private


に設定されているので


親クラスGameCharacterのメンバ関数


statusDataDisplay()

が用いられた


子クラスDragon型のオブジェクトPokkyのメンバ関数


Pokky.statusDataDisplay()


を使用することはできません


ですが


子クラスDragonのクラス宣言内のメンバ関数宣言


void statusDataDisplay2(string a, int b, int c);


のアクセス指定子は


publicに設定されています


そして


Pokkyの子クラスDragon💖💖💖💖💖💖型のオブジェクト宣言


Dragon Pokky;


を実行して


子クラスDragon型のオブジェクトPokkyを作製しても


子クラスDragonのメンバ変数となった親クラスGameCharacterのメンバ変数


name

HP

MP

が用いられた


子クラスDragon型のオブジェクトPokkyのメンバ変数


Pokky.name

Pokky.HP

Pokky.MP


は使用することはできません


ですので


子クラスDragon型のオブジェクトPokkyのメンバ変数


Pokky.name

Pokky.HP

Pokky.MP


を使用して


          🍎🐤直接🍎🐤



Pokky.name = "ポッキー";

Pokky.HP = 15;

Pokky.MP = 5;


のようにデータを代入することはできません


しかし


子クラスDragonのメンバ関数


statusDataDisplay2(string a, int b, int c);


が用いられた


子クラスDragon型のオブジェクトPokkyのメンバ関数


Pokky.statusDataDisplay2("ポッキー", 15, 5);


を実行することにより




          🍈🐤間接的に🍈🐤



子クラスDragon型のオブジェクトPokkyのメンバ変数


Pokky.name

Pokky.HP

Pokky.MP



Pokky.name = "ポッキー";

Pokky.HP = 15;

Pokky.MP = 5;


のように


データを代入することができます


子クラスDragon型のオブジェクトPokkyのメンバ関数


Pokky.statusDataDisplay2("ポッキー", 15, 5);


が実行されると


🌞🌞🌞クラスDragonのメンバ関数statusDataDisplay2(string a, int b, int c)の定義🌞🌞🌞

👇


void Dragon::statusDataDisplay2(string a, int b, int c) {


name = a;

HP = b;

MP = c;


cout << name << "\n";

cout << "HP " << HP << "\n";

cout << "MP " << MP << "\n";

}


👆



name

HP

MP


子クラスDragon型のオブジェクトPokkyのメンバ変数


Pokky.name

Pokky.HP

Pokky.MP



a

b

c

"ポッキー"

15

5

が代入された


Pokky.name="ポッキー";

Pokky.HP =15;

Pokky.MP =5;


cout << Pokky.name << "\n";

cout << "HP " << Pokky.HP << "\n";

cout << "MP " << Pokky.MP << "\n";


が実行されるので


プログラムの実行結果に


ポッキー

HP 15

MP 5


が表示されることになります」


そのプログラムはこちらです

👇

#include <iostream>

#include <string>//文字列を取り扱うためにヘッダファイル <string>をインクルードしています

using namespace std;


//👇🌞🌞🌞クラスGameCharacterです🌞🌞🌞

class GameCharacter {


public:

string name;

int HP;

int MP;


void statusDataDisplay();



};



void GameCharacter::statusDataDisplay() {


cout << name << "\n";

cout << "HP " << HP << "\n";

cout << "MP " << MP << "\n";

}





//👇🌞🌞🌞クラスGameCharacterを継承したクラスDragonです🌞🌞🌞


class Dragon :private GameCharacter {

public:

void statusDataDisplay2(string a, int b, int c);


};



void Dragon::statusDataDisplay2(string a, int b, int c) {


name = a;

HP = b;

MP = c;


cout << name << "\n";

cout << "HP " << HP << "\n";

cout << "MP " << MP << "\n";

}


int main() {


Dragon Pokky;


Pokky.statusDataDisplay2("ポッキー", 15, 5);


return 0;

}


プログラムの実行結果


ポッキー

HP 15

MP 5














  • Twitterで共有
  • Facebookで共有
  • はてなブックマークでブックマーク

作者を応援しよう!

ハートをクリックで、簡単に応援の気持ちを伝えられます。(ログインが必要です)

応援したユーザー

応援すると応援コメントも書けます

新規登録で充実の読書を

マイページ
読書の状況から作品を自動で分類して簡単に管理できる
小説の未読話数がひと目でわかり前回の続きから読める
フォローしたユーザーの活動を追える
通知
小説の更新や作者の新作の情報を受け取れる
閲覧履歴
以前読んだ小説が一覧で見つけやすい
新規ユーザー登録無料

アカウントをお持ちの方はログイン

カクヨムで可能な読書体験をくわしく知る