ポリモーフィズム(多態性)が用いられたプログラムを実行してみましょう その1
ソーラー「今日はポリモーフィズム
が用いられたプログラムを観察してみたいと思います
ポリモーフィズム(多態性)
とは何のことかな
その説明の
準備としてはですね
そうだなあ
今まで登場した
親クラスGameCharacter
と
子クラスDragon
子クラスHuman
子クラスElf
に登場してもらおっか(#^^#)
親クラスGameCharacterのメンバ関数宣言
void statusDataDisplay();
に
virtual void statusDataDisplay();
や
virtual void statusDataDisplay()=0;
のように
virtual
もしくは
virtual
と
=0;
をくっつけて
親クラスGameCharacterのメンバ関数statusDataDisplay()
を
仮想関数
もしくは
純粋仮想関数に
設定します
その状態で
子クラス側で
🌞親クラスGameCharacterのメンバ関数statusDataDisplay()🌞
と
🌞"同じ名前"の子クラスDragonのメンバ関数statusDataDisplay()を設定する🌞
すなわち
親クラスGameCharacterのメンバ関数statusDataDisplay()
を
子クラスDragonのメンバ関数statusDataDisplay()で
オーバーライドしておきます
そして
Pokkyの子クラスDragon型のオブジェクト宣言
Dragon Pokky;
を実行して
子クラスDragon型のオブジェクトPokkyを作製したとします
次に
aの親クラスGameCharacter*型のポインタ変数宣言,初期化
GameCharacter* a=&Pokky;
を実行することにより
親クラスGameCharacter*型のポインタ変数aに
子クラスDragon型のオブジェクトPokkyのアドレス&Pokkyを代入して
a->statusDataDisplay();
を実行した場合は
親クラスGameCharacterのメンバ関数statusDataDisplay()
は
仮想関数もしくは純粋仮想関数で
子クラスDragonのメンバ関数statusDataDisplay()
によってオーバーライドされているので
親クラスGameCharacterのメンバ関数statusDataDisplay()の定義は用いられず
子クラスDragonのメンバ関数statusDataDisplay()の定義が用いられた
子クラスDragon型のオブジェクトPokkyの(オーバーライドしている)メンバ関数
Pokky.statusDataDisplay();
に相当するものが実行されることになります
さらに
子クラスHumanに
メンバ関数statusDataDisplay()が設定されているとします
そして
親クラスGameCharacter*型のポインタ変数aに
違う子クラスHuman型のオブジェクトLylianeのアドレス&Lyliane
を代入して
a->statusDataDisplay()
を実行すると
親クラスGameCharacterのメンバ関数statusDataDisplay()
は
仮想関数もしくは純粋仮想関数で
子クラスHumanのメンバ関数statusDataDisplay()
によってオーバーライドされているので
親クラスGameCharacterのメンバ関数statusDataDisplay()の定義は用いられず
子クラスHumanのメンバ関数statusDataDisplay()の定義が用いられた
子クラスHuman型のオブジェクトLylianeの(オーバーライドしている)メンバ関数
Lyliane.statusDataDisplay();
に相当するものが実行されることになります
もちろん
a->statusDataDisplay()
の形式はそのままでOKというわけです
さらに
子クラスElfに
メンバ関数statusDataDisplay()が設定されているとします
そして
親クラスGameCharacter*型のポインタ変数aに
違う子クラスElf型のオブジェクトSylphineのアドレス&Sylphine
を代入して
a->statusDataDisplay()
を実行すると
親クラスGameCharacterのメンバ関数statusDataDisplay()
は
仮想関数もしくは純粋仮想関数で
子クラスElfのメンバ関数statusDataDisplay()
によってオーバーライドされているので
親クラスGameCharacterのメンバ関数statusDataDisplay()の定義は用いられず
子クラスElfのメンバ関数statusDataDisplay()の定義が用いられた
子クラスElf型のオブジェクトSylphineの(オーバーライドしている)メンバ関数
Sylphine.statusDataDisplay();
に相当するものが実行されることになります
もちろん
a->statusDataDisplay()
の形式はそのままでOKというわけです
そのことを示すプログラムはこちらです
👇
#include <iostream>
#include <string>//文字列を取り扱うためにヘッダファイル <string>をインクルードしています
using namespace std;
class GameCharacter {
public:
string name;
int HP;
int MP;
virtual void statusDataDisplay() = 0;
};
class Human :public GameCharacter {
public:
int TP;//👈Human(人間)型のキャラクターだけに備わっているテクニックポイントです
void statusDataDisplay();
};
//👇🌞🌞🌞子クラスHumanのメンバ関数statusDataDisplay() の定義です🌞🌞🌞
void Human::statusDataDisplay() {
cout << name << "\n";
cout << "HP " << HP << "\n";
cout << "MP " << MP << "\n";
cout << "TP " << TP << "\n"; //👈Human(人間)型のキャラクターだけに備わっているテクニックポイントを表示することができます
}
class Dragon :public GameCharacter {
public:
int DP;//👈ドラゴン型のキャラクターだけに備わっているドラゴンポイントです
void statusDataDisplay();
};
//👇🌞🌞🌞子クラスDragonのメンバ関数statusDataDisplay() の定義です🌞🌞🌞
void Dragon::statusDataDisplay() {
cout << name << "\n";
cout << "HP " << HP << "\n";
cout << "MP " << MP << "\n";
cout << "DP " << DP << "\n";//👈ドラゴン型のキャラクターだけに備わっているドラゴンポイントを表示することができます
}
class Elf :public GameCharacter {
public:
int EP;//👈エルフ型のキャラクターだけに備わっているエルフポイントです
void statusDataDisplay();
};
//👇🌞🌞🌞子クラスElfのメンバ関数statusDataDisplay() の定義です🌞🌞🌞
void Elf::statusDataDisplay() {
cout << name << "\n";
cout << "HP " << HP << "\n";
cout << "MP " << MP << "\n";
cout << "EP " << EP << "\n";//👈エルフ型のキャラクターだけに備わっているエルフポイントを表示することができます
}
int main() {
Human Lyliane;
Lyliane.name = "リリアーネ";
Lyliane.HP = 10;
Lyliane.MP = 8;
Lyliane.TP = 5;
Dragon Pokky;
Pokky.name = "ポッキー";
Pokky.HP = 20;
Pokky.MP = 3;
Pokky.DP = 2;
Elf Sylphine;
Sylphine.name = "シルフィ";
Sylphine.HP = 5;
Sylphine.MP = 8;
Sylphine.EP = 15;
GameCharacter* a;
a = &Pokky;
a->statusDataDisplay();
a = &Lyliane;
a->statusDataDisplay();
a = &Sylphine;
a->statusDataDisplay();
return 0;
}
プログラムの実行結果
ポッキー
HP 20
MP 3
DP 2
リリアーネ
HP 10
MP 8
TP 5
シルフィ
HP 5
MP 8
DP 15
ソーラー「このプログラムでは
Human Lyliane;
Lyliane.name = "リリアーネ";
Lyliane.HP = 10;
Lyliane.MP = 8;
Lyliane.TP = 5;
Dragon Pokky;
Pokky.name = "ポッキー";
Pokky.HP = 20;
Pokky.MP = 3;
Pokky.DP = 2;
Elf Sylphine;
Sylphine.name = "シルフィ";
Sylphine.HP = 5;
Sylphine.MP = 8;
Sylphine.EP = 15;
を実行したのち
親クラスGameCharacter*型のポインタ変数宣言
GameCharacter* a;
を実行しています
こうして作成された
🌞親クラスGameCharacter*型のポインタ変数aに🌞
a = &Pokky;
と
🌞子クラスDragon型のオブジェクトPokkyのアドレス&Pokky🌞
を代入すると
a->statusDataDisplay();
の実行の際
親クラスGameCharacterのメンバ関数statusDataDisplay()
は
純粋仮想関数で
子クラスDragonのメンバ関数statusDataDisplay()
によってオーバーライドされているので
GameCharacter*型のポインタ変数aは
親クラスGameCharacterのメンバ関数statusDataDisplay()の定義
でなく
子クラスDragonのメンバ関数statusDataDisplay()の定義
👇
void Dragon::statusDataDisplay() {
cout << name << "\n";
cout << "HP " << HP << "\n";
cout << "MP " << MP << "\n";
cout << "DP " << DP << "\n";//👈ドラゴン型のキャラクターだけに備わっているドラゴンポイントを表示することができます
}
👆
にアクセスすることになり
name
HP
MP
DP
に
子クラスDragon型のオブジェクトPokkyのメンバ変数
Pokky.name
Pokky.HP
Pokky.MP
Pokky.DP
が代入されたものが実行されることになります
ですので
コマンドプロンプト画面に
ポッキー
HP 20
MP 3
DP 2
が表示されることになります
次に
GameCharacter*型のポインタ変数aに
a = &Lyliane;
と
子クラスHuman型のオブジェクトLylianeのアドレス&Lylianeを代入すると
a->statusDataDisplay();
の実行の際
親クラスGameCharacterのメンバ関数statusDataDisplay()
は
純粋仮想関数で
子クラスHumanのメンバ関数statusDataDisplay()
によってオーバーライドされているので
a->statusDataDisplay();
の実行の際
GameCharacter*型のポインタ変数aは
親クラスGameCharacterのメンバ関数statusDataDisplay()の定義
でなく
子クラスHumanのメンバ関数statusDataDisplay()の定義
👇
void Human::statusDataDisplay() {
cout << name << "\n";
cout << "HP " << HP << "\n";
cout << "MP " << MP << "\n";
cout << "TP " << TP << "\n"; //👈Human(人間)型のキャラクターだけに備わっているテクニックポイントを表示することができます
}
👆
にアクセスすることになり
name
HP
MP
TP
に
子クラスHuman型のオブジェクトLylianeのメンバ変数
Lyliane.name
Lyliane.HP
Lyliane.MP
Lyliane.TP
が代入されたものが実行されることになります
ですので
コマンドプロンプト画面に
リリアーネ
HP 10
MP 8
TP 5
が表示されることになります
次に
GameCharacter*型のポインタ変数aに
a = &Sylphine;
と
子クラスElf型のオブジェクトSylphineのアドレス&Sylphineを代入すると
親クラスGameCharacterのメンバ関数statusDataDisplay()
は
純粋仮想関数で
子クラスElfのメンバ関数statusDataDisplay()
によってオーバーライドされているので
a->statusDataDisplay();
の実行の際
GameCharacter*型のポインタ変数aは
親クラスGameCharacterのメンバ関数statusDataDisplay()の定義
でなく
子クラスElfのメンバ関数statusDataDisplay()の定義
👇
void Elf::statusDataDisplay() {
cout << name << "\n";
cout << "HP " << HP << "\n";
cout << "MP " << MP << "\n";
cout << "EP " << EP << "\n";//👈エルフ型のキャラクターだけに備わっているエルフポイントを表示することができます
}
👆
にアクセスすることになり
name
HP
MP
EP
に
子クラスElf型のオブジェクトSylphineのメンバ変数
Sylphine.name
Sylphine.HP
Sylphine.MP
Sylphine.DP
が代入されたものが実行されることになります
ですので
コマンドプロンプト画面に
シルフィ
HP 5
MP 8
TP 15
が表示されることになります
つまり
a->statusDataDisplay();
の実行の際
ポインタ変数aに代入されるアドレスを
&Pokky
&Lyliane
&Sylphine
と変更するだけで
実行される関数を入れ替えることができるというわけです
このことを
ポリモーフィズム(多態性)
といいます」
新規登録で充実の読書を
- マイページ
- 読書の状況から作品を自動で分類して簡単に管理できる
- 小説の未読話数がひと目でわかり前回の続きから読める
- フォローしたユーザーの活動を追える
- 通知
- 小説の更新や作者の新作の情報を受け取れる
- 閲覧履歴
- 以前読んだ小説が一覧で見つけやすい
アカウントをお持ちの方はログイン
ビューワー設定
文字サイズ
背景色
フォント
組み方向
機能をオンにすると、画面の下部をタップする度に自動的にスクロールして読み進められます。
応援すると応援コメントも書けます