しいたけです。
好きなキノコはキクラゲです。(あだ名しいたけなのに)
継承などの学習をしていたところ、記事のネタを思いついたので、今回のテーマは継承、オーバーライド、ポリモーフィズムです。
マリオの変身について
突然ですが、スーパーマリオとファイアマリオの違いを説明できますか?
服の色だけではありません。ファイアボールが使えるようになります。
また、スーパーだとクリボーに2回触るとミスになりますが、ファイアだと3回まで耐えられます。(初代だとどちらも2回というのは置いておいて)
他に大きな変化はありますか?特にないですよね。
つまり 「ファイアマリオはスーパーマリオをベースに作られたもの」 と言えます。
言い換えればファイアマリオはスーパーマリオの能力を受け継いでいます。
これこそが「継承」です。
継承とは?
class FireMario extends Mario {
private int fireballCount;
public FireMario() {
super(); // 親クラスのコンストラクタを呼び出す
this.fireballCount = 10; // ファイアボールを持っている
}
// 新たにファイアマリオ特有の能力を追加
public void throwFireball() {
if (fireballCount > 0) {
fireballCount--;
System.out.println("Fire Mario throws a fireball!");
} else {
System.out.println("No fireballs left!");
}
}
Mario
というクラスがあったとき、extends
によって継承が行われFireMario
クラスを生成します。
この時、元となっているMario
をスーパークラス、extends
されたFireMario
をサブクラスと言います。
オーバーライドとは?
class Mario {
private int health;
// 中略
public Mario() {
this.name = "Super Mario";
this.health = 2; // スーパーマリオの体力を2に設定
}
public void showStatus() {
System.out.println(name + " has " + health + " health.");
}
}
class FireMario extends Mario {
private int fireballCount;
private int health; // ファイアマリオの体力を独自に持たせる
//中略
@Override
public void showStatus() {
super.showStatus(); // 親クラスのメソッドを呼び出す
System.out.println("Fire Mario has " + fireballCount + " fireballs left.");
}
}
今回の例では、showStatus
において、スーパーマリオの状態だと体力が2であることを示しています。
ここでファイアマリオだとファイアボールを持っている個数まで表示させたいです。しかしこのままでは表示できません。
これをどのようにして解決しているか。「もう一度定義している」のです。
スーパークラスにも、サブクラスにもshowStatus
があります。
ここでファイアマリオの場合に体力とファイアボールの個数を出力させるように、showStatus
を定義しなおします。
そのあとに別のクラスでそれぞれのインスタンスのshowStatus
を実行すると、スーパーマリオとファイアマリオごとに別々の出力内容となります。
ポリモーフィズムとは?
少し例を変えてみましょう。
マリオとルイージのジャンプ力についてです。ルイージはマリオより高くジャンプできるという設定があります。
class Player {
public void jump() {
System.out.println("The player jumps!");
}
}
class Mario extends Player {
@Override
public void jump() {
System.out.println("Mario jumps 2 meters high!");
}
}
class Luigi extends Player {
@Override
public void jump() {
System.out.println("Luigi jumps 3 meters high!");
}
}
ここで大事なことは 「マリオもルイージもジャンプができる」 ということです。 ここに付随した情報である 「ルイージはマリオより高くジャンプできる」 といった情報を加えます。
ジャンプという動作を細分化して、マリオは2メートル、ルイージは3メートルジャンプできるといった情報を加えます。
このように、継承されたクラスごとに異なる動作がなされています。これが「ポリモーフィズム」です。
オーバーライドとポリモーフィズムって一緒じゃね?
ここでこう思った人もいるでしょう。それは違います。
クリボーとクリボンぐらい違います。下記のように覚えてください。
オーバーライド > ポリモーフィズム
前提として、オーバーライドされていないとポリモーフィズムできません。
スーパークラスで定義されたメソッドを「再定義」することがオーバーライドです。そして再定義されたメソッドを「処理・実行する」ことがポリモーフィズムです。ポリモーフィズムはオーバーライドされたメソッドを活用しているのです。
まとめ
継承:extends
によってスーパークラスの情報を持ち出し、サブクラスを作成する
オーバーライド:メソッドの再定義
ポリモーフィズム:オーバーライドされたメソッドを処理・実行する
ちなみにクリボーのモチーフは「しいたけ」です。It's-a me?????