仕様変更時に変更量を減らせるアップキャスト(Java)


アップキャストについて

アップキャストとは

アップキャストとは、サブクラス(子クラス)が暗黙的にスーパークラス(親クラス)として振る舞うのを可能にする機能のことだ。

使うことで何が実現できるのか

開発において、仕様変更は付きものである。
そういった仕様変更時に、アップキャストを利用してプログラムを書いていれば、変更に伴うプログラムの書き換えを最小限に止めることができるのだ。

プログラムから例を示そう。

ソースコード

Main.java
public class Main{
  public static void main(String[] args){
    Life_form life_form = new Life_form();
    life_form.makeSound();

// アップキャスト 
    life_form = new Cat();
    life_form.makeSound();
  }
}
Life_form.java
//親クラス 
public class Life_form{
  public void makeSound(){
    System.out.println("???");
  }
}
Cat.java
//子クラス
public class Cat extends Life_form{
  @Override
  public void makeSound(){
    System.out.println("にゃあ");
  }

  public void catPunch(){
    System.out.println("ネコパン");
  }

}
Dog.java
//「仕様変更よろしく」の項目で使用します。
public class Dog extends Life_form {
  @Override
  public void makeSound(){
    System.out.println("クゥーン!");
  }

  public void dogAttack(){
    System.out.println("かみつく");
  }
}

Life_formクラスとCatクラスについての説明

・Life_form(いきもの)クラスはmakeSound関数を持っている。
・CatクラスはLifeformクラスを継承しており、makeSound関数を再定義(オーバーライド)している。
・また、Catクラスは親クラスにはない限定の関数、catPunch関数を持っている。

なお、Dogクラスは以下の項目、「仕様変更よろしく」で使用する。作りはCatクラスと同じで、makeSoundをオーバーライドしており、Dogクラス限定のdogAttackを持っている。

Mainクラスの説明

Mainクラスで注目して欲しいのは
life_form = new Cat();
としているところだ。

親クラスへの子クラス代入。
これがアップキャストである。

実行結果

実行結果は以下のようになる。

少し見にくいが、アップキャストしたことで、CatインスタンスのmakeSound()がlife_formから呼ばれていることがわかると思う。
つまり、life_form = new Cat();した後のlife_formの実体はCatのインスタンスなのである。

仕様変更よろしく

さて、このプログラムのCatインスタンスをDogインスタンスに変えてくれと頼まれた場合、変更箇所は次の一点で済む。

life_form = new Cat();
->life_form = new Dog();

もしアップキャストが機能として存在していなかったなら、変更は次のようになるだろう。

1個目
life_form = new Cat();
->Dog dog = new Dog();

2個目
life_form.makeSound();
->dog.makeSound();

インスタンス生成をDog型でする必要がまずでてきて、さらに使用するところでもdogを使わなくてはいけなくなる。

そんなに変わらないじゃないかと思うかもしれない。
だがそれは、これがきわめて小規模なプログラムだからだ。
大規模な開発になればなるほど、変更点が増え、変更量が増加する。

仕様変更に強いプログラムを作ることは重要だ。そして、javaにはそれを実現するための機能がある。
うまく使っていきたい。