🌞親クラスから子クラスへ継承が行われるとクラスの型が違う親クラス型のオブジェクトに子クラス型のオブジェクトを代入することができるようになるんです🌞

🌞親クラスから子クラスへクラスの継承が行われるとクラスの型が違う親クラス型のオブジェクトに子クラス型のオブジェクトを代入することができるようになるんです🌞


つ・づ・き・・・😊




 ソーラー「親クラスから子クラスへクラスの継承が行われると



   🌞クラスの型が違う親クラス型のオブジェクトに🌞



   🌞子クラス型のオブジェクトを代入することができるようになるんです🌞



もうちょっち付け足すと


自作関数(クラスのメンバ関数)の引数となっている


親クラス型のオブジェクト宣言に


子クラス型のオブジェクトを


代入することができるようになるんです


このことがなぜ重要な働きとなるかを


考察してみようよ😊💖!



それではLet's Challenge joy!



次のプログラムをご覧ください!



#include <iostream>

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

using namespace std;


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

class GameCharacter {


public:

string name;

int HP;

int MP;


void statusDataDisplay();


//クラスGameCharacterにはuseFireRecovery(GameCharacter& a)を設定しません

};



void GameCharacter::statusDataDisplay() {


cout << name << "\n";

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

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

}





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


class Dragon :public GameCharacter {

public:


int DP;//👈🌞ドラゴン(Dragon)型のキャラクターだけに備わっているドラゴンポイントです

void useFireRecovery(GameCharacter& a);


void DragonstatusDataDisplay();


};



void Dragon::useFireRecovery(GameCharacter& a) {

cout << name << "は灼熱のフレアを" << a.name << "に吐いた !" << "\n";

cout << a.name << "は灼熱のフレアを受け燃え上がった!" << "\n";


a.HP += 10;


cout << a.name << "の体力は10回復した" << "\n";


}


void Dragon::DragonstatusDataDisplay() {


cout << name << "\n";

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

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

cout << "DP " << DP << "\n";


}


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


class Human :public GameCharacter {

public:


int IP;//👈🌞人間(Human)型のキャラクターだけに備わっているアイドル(人気度)ポイントです

void useSuperMarket();

void HumanstatusDataDisplay();

};


//👇🌞🌞🌞クラスHumanのメンバ関数の定義です🌞🌞🌞

void Human::useSuperMarket() {

cout << name << "はスーパーマーケットにいった" << "\n";

cout << name << "は小豆バーをみつけた!" << "\n";

HP += 10;


cout << name << "のHPは10回復した!" << "\n";

}


void Human::HumanstatusDataDisplay() {


cout << name << "\n";

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

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

cout << "IP " << IP << "\n";


}







int main() {


GameCharacter Lyliane;


Lyliane.name = "リリアーネ";

Lyliane.HP = 10;

Lyliane.MP = 8;


Dragon Pokky;

Pokky.name = "ポッキー";

Pokky.HP = 15;

Pokky.MP = 5;


Lyliane.statusDataDisplay();

Pokky.statusDataDisplay();


Pokky.useFireRecovery(Lyliane);


Lyliane.statusDataDisplay();

Pokky.statusDataDisplay();



return 0;

}


プログラムの実行結果


リリアーネ

HP 10

MP 8

ポッキー

HP 15

MP 5

ポッキーは灼熱のフレアをリリアーネに吐いた!

リリアーネは灼熱のフレアを受け燃え上がった!

リリアーネの体力は10回復した

リリアーネ

HP 20

MP 8

ポッキー

HP 15

MP 5


ソーラー「このプログラムでは


1.クラスGameCharacter


2.クラスGameCharacterを親クラスとして継承した子クラスDragon


3.クラスGameCharacterを親クラスとして継承した子クラスHuman



3つのクラスが設定,用いられています



そして


プログラムの中で


Pokky.useFireRecovery(Lyliane);


が実行される際


クラスDragonのメンバ関数

useFireRecovery(GameCharacter& a)の引数となっている


GameCharacter& aに


GameCharacter型のオブジェクト宣言


GameCharacter Lyliane;


によって生成される


GameCharacter型のオブジェクトLyliane


が代入されていますが


親クラスGameCharacterを継承した子クラスHuman型のオブジェクト宣言


Human Lyliane;


によって生成される


子クラスHuman型のオブジェクトLyliane


クラスDragonのメンバ関数

useFireRecovery(GameCharacter& a)の引数GameCharacter& aに代入した


Pokky.useFireRecovery(Lyliane);


を実行することもできますし


親クラスGameCharacterを継承した子クラスFairy型のオブジェクト宣言


Fairy Silphy;


によって生成される


子クラスFairy型のオブジェクトSilphy



クラスDragonのメンバ関数

useFireRecovery(GameCharacter& a)の引数GameCharacter& aに代入した


Pokky.useFireRecovery(Silphy);


を実行することもできます


このことは


とても


        🌞大切なことなんです🌞




             もし



Pokky.useFireRecovery(Lyliane);


が実行される際


引数に


GameCharacter Lyliane;


によって生成される


親クラスGameCharacter型のオブジェクトLyliane


しか代入できないのであれば困ったことが起こるんです」


マックス「困ったこと?


いやん ぜんぜん困らないんだが・・・」


ソーラー「


Pokky.useFireRecovery(Lyliane);


が実行される際


引数に


GameCharacter Lyliane;


によって生成される


親クラスGameCharacter型のオブジェクトLyliane


しか代入できないということになると


Pokky.useFireRecovery(Lyliane);


が作用することができるのは

 


   🌞GameCharacterLyliane🌞


ということになります」


マックス「まあ そうだよな


親クラスGameCharacter型のオブジェクトであれば


Lyliane

でも

Elfine

でも

Shilphy

でも

いいよな


ソーラー「そうなると


親クラスGameCharacter型のオブジェクトLyliane


を引数に用いた


Pokky.useFireRecovery(Lyliane);


は実行できて



親クラスGameCharacterを継承した子クラスHuman型のオブジェクトLyliane


を引数に用いた


Pokky.useFireRecovery(Lyliane);


は実行できないということになります


同様に


親クラスGameCharacterを継承した子クラスFairy(妖精)型のオブジェクトShilphy


を引数に用いた


Pokky.useFireRecovery(Shilphy);


も実行できないということになります」


マックス「まあ、そうなる・・よな」


ソーラー「ということは


必要なのは


親クラスGameCharacterだけで


親クラスGameCharacterを継承した子クラスHuman

親クラスGameCharacterを継承した子クラスDragon

親クラスGameCharacterを継承した子クラスFairy


は必要ないということになってしまうとおもいませんか?


親クラスGameCharacter型のオブジェクトLyliane


を引数に用いた


Pokky.useFireRecovery(Lyliane);


しか実行できないからですね



マックス「んん?」


ソーラー「そもそも


親クラスGameCharacterを継承した子クラスHumanを生成したのは


子クラスHuman(人間)型のオブジェクトLylianeを生成するためです


なぜ


子クラスHuman(人間)型のオブジェクトLylianeを生成したのかというと


親クラスGameCharacter型のオブジェクトLylianeでは



対象としてみるモノ=プロトタイプオブジェクトである


ゲームキャラクター


リリアーネ


ステータスデータ

name

HP

MP

ステータスデータ

name

HP

MP

を表示する


ことしか取り扱うことができなかったからなんです




親クラスGameCharacter型のオブジェクトLylianeでは



対象としてみるモノ=プロトタイプオブジェクトである


ゲームキャラクター


リリアーネ



ステータスデータ

name

HP

MP

ステータスデータ

name

HP

MP

を表示する


ことしかとりあつかえませんが



親クラスGameCharacterを継承した


子クラスHumanの場合


子クラスHuman型のオブジェクトLylianeを生成すれば


子クラスHuman型のオブジェクトLylianeは


ゲームキャラクター


リリアーネ



ステータスデータ

name

HP

MP

IP//👈ここが増えました

ステータスデータ

name

HP

MP

IP//👈ここが増えました

を表示する


ことに加え


Human(人間)型のキャラクターだけに備わっている


小豆バーを買いに行って体力を回復する//👈ここが増えました



ということまでとりあつかうことができるからなんです」



マックス「スーパーに買い物に行くっていうあれか・・・」



ソーラー「


ですから


親クラスGameCharacterを継承した子クラスHuman

親クラスGameCharacterを継承した子クラスDragon

親クラスGameCharacterを継承した子クラスFairy


などは


必要な


欠かせないクラスなんです


いらないクラスではありません


ですので


親クラスGameCharacterを継承した子クラスHuman(人間)型のオブジェクトLylianeを


引数に用いた


Pokky.useFireRecovery(Lyliane);


が実行できないとなると


クラスDragonのメンバ関数useFireRecoveryの定義

👇


void Dragon::useFireRecovery(GameCharacter& a) {

cout << name << "は灼熱のフレアを" << a.name << "に吐いた !" << "\n";

cout << a.name << "は灼熱のフレアを受け燃え上がった!" << "\n";


a.HP += 10;


cout << a.name << "の体力は10回復した" << "\n";


}


👆

引数部分のGameCharacter& a



Human& a


に切り替える必要がありますね


そうなると


クラスDragonのメンバ関数useFireRecoveryの定義は

👇

               👇こ・こ   

void Dragon::useFireRecovery(Human& a) {

cout << name << "は灼熱のフレアを" << a.name << "に吐いた !" << "\n";

cout << a.name << "は灼熱のフレアを受け燃え上がった!" << "\n";


a.HP += 10;


cout << a.name << "の体力は10回復した" << "\n";


}


となります


このように


引数にHuman& aが用いられていれば


親クラスGameCharacterを継承した子クラスHuman(人間)型のオブジェクトLylianeを


引数に代入した


Pokky.useFireRecovery(Lyliane);


が実行できる


やったね


めでたし めでたし


となりそうですが


このように


クラスDragonのメンバ関数useFireRecoveryの引数部分



Human& a


に設定してしまうと


Human& a


に代入できるのは


親クラスGameCharacterを継承した子クラスHuman(人間)型のオブジェクトだけとなってしまいます


親クラスGameCharacterを継承した子クラスHuman(人間)型のオブジェクトLylianeを


引数に代入した


Pokky.useFireRecovery(Lyliane);


は実行できても



親クラスGameCharacterを継承した子クラスFairy(妖精)型のオブジェクトShilphyを


引数に代入した


Pokky.useFireRecovery(Shilphy);


は実行できないということになります


つまり


ゲーム内において


人間(Human)型のキャラクター


リリアーネのHPは


ドラゴン(Dragon)型のキャラクター ポッキーの


特殊能力ファイヤーフレアにより回復できても



妖精(Fairy)型のキャラクター


シルフィのHPは


ドラゴン型のキャラクター ポッキーの


特殊能力ファイヤーフレアにより回復できないことになります


そこで


クラスDragonのメンバ関数useFireRecoveryの定義

👇


void Dragon::useFireRecovery(Human& a) {

cout << name << "は灼熱のフレアを" << a.name << "に吐いた !" << "\n";

cout << a.name << "は灼熱のフレアを受け燃え上がった!" << "\n";


a.HP += 10;


cout << a.name << "の体力は10回復した" << "\n";


}


👆

引数部分のHuman& a



Fairy& a


に切り替えてしまうと


今度は


親クラスGameCharacterを継承した子クラスFairy(妖精)型のオブジェクトShilphyを


引数Fairy& aに代入した


Pokky.useFireRecovery(Shilphy);


は実行できても


親クラスGameCharacterを継承した子クラスHuman(人間)型のオブジェクトLylianeを


引数Fairy& aに代入する


Pokky.useFireRecovery(Lyliane);


は実行できないということになります


これでは


妖精(Fairy)型のキャラクター


シルフィのHPは


ドラゴン(Dragon)型のキャラクター ポッキーの


特殊能力ファイヤーフレアにより回復できても


人間(Human)型のキャラクター


リリアーネのHPは


ドラゴン型のキャラクター ポッキーの


特殊能力ファイヤーフレアにより回復できないことになります」


マックス「なるほどのう


だから


クラスDragonのメンバ関数

useFireRecovery(GameCharacter& a)の引数に


親クラスGameCharacterが用いられた


GameCharacter& a


が設定されているのか・・・


GameCharacter& a


が設定されていれば


普通に


クラスDragonのメンバ関数

useFireRecovery(GameCharacter& a)の引数


GameCharacter& aに


LylianeのGameCharacter型のオブジェクト宣言


GameCharacter Lyliane;


によって生成される


    親クラスGameCharacter型のオブジェクトLyliane


を代入した


Pokky.useFireRecovery(Lyliane);


を実行することができるだけでなく



  親クラスGameCharacterを継承した子クラスHuman型のオブジェクト宣言


Human Lyliane;


によって生成される


    子クラスHuman型のオブジェクトLyliane


クラスDragonのメンバ関数


useFireRecovery(GameCharacter& a)の引数GameCharacter& aに代入した


Pokky.useFireRecovery(Lyliane);


を実行することもでき


親クラスGameCharacterを継承した子クラスFairy型のオブジェクト宣言


Fairy Silphy;


によって生成される


    子クラスFairy型のオブジェクトSilphy



クラスDragonのメンバ関数


useFireRecovery(GameCharacter& a)の引数GameCharacter& aに代入した


Pokky.useFireRecovery(Silphy);


を実行することもできるからな



それにしても

👇


親クラスから子クラスへ継承が行われると



   🌞クラスの型が違う親クラス型のオブジェクトに🌞



   🌞子クラス型のオブジェクトを代入することができるようになるんです🌞



もうちょっち付け足すと


自作関数(クラスのメンバ関数)の引数となっている


親クラス型のオブジェクト宣言に


子クラス型のオブジェクトを


代入することができるようになるんです


👆

このシステムは


優秀だな


めっちゃんこ かんがえられているな」







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

作者を応援しよう!

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

応援したユーザー

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

新規登録で充実の読書を

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

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

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