Part6では,カプセル化,継承と並んでオブジェクト指向の3大要素と呼ばれる「ポリモーフィズム(多態性)について学びます。ポリモーフィズムを使う最大の利点は,重複するメソッド名を利用できることにあります。これにより,プログラムの見通しや再利用性が格段に良くなります。

 Part6のテーマはポリモーフィズム。Java言語の学習者が,最も難解に感じるポイントの一つです。理解しにくいという人は,ポリモーフィズムが何の役に立つのかイメージできないことが多いようです。

 ポリモーフィズムを使う最大の利点は,重複するメソッド名を利用できることにあります。例えば,C言語では,異なる関数に同じ名前を付けることができません。似たような関数でも,ちょっとだけ機能が違うだけで違う名前を付けなければなりません。一方,ポリモーフィズムを利用できる言語なら,同じような機能を持ったメソッドに同じ名前を付けられます。実は,これがプログラムの読みやすさや再利用のしやすさに大きく影響を与えるのです。

 Javaの処理系が備えるクラスライブラリも,ポリモーフィズムを多く利用しています。つまり,Javaのクラスライブラリを利用するには,ポリモーフィズムについて理解しておかなければならないということです。

同じメソッド名で場面に応じた動作をさせる

 ここでは,最初にポリモーフィズムを利用しないサンプルを取り上げてポリモーフィズムの利点を説明していきます。ポリモーフィズムという概念を簡単に説明すると,「同じメッセージに対する動作がオブジェクトごとに異なること」です。Java言語では「同じメッセージ」の部分は「同じメソッド」に読み換えられます。つまり,いろいろなオブジェクトが同じ名前のメソッドを持てるということです。

 同じ名前のメソッドが使えると,何が便利なのでしょうか。リスト1をご覧ください。

public class Test_a {
  public static void displayOut(String message) {
    System.out.println("ディスプレイに「" + message + "」と表示
    します");
  }
  public static void printOut(String message) {
    System.out.println("「" + message + "」という文字列を印刷し
    ます");
  }
  public static void main(String[] args) {
    String message = "日経ソフトウエア";
    displayOut(message);
    printOut(message);
  }
}
リスト1●文字列を表示するメソッド

 displayOutとprintOutの二つのメソッドを作って,mainメソッドでそれぞれを呼び出しています。こうしたメソッドでいろいろな機器に出力させるには,それぞれメソッドを用意する必要があります。機器の数が少ないうちはいいのですが,10や20にも増えてくるとメソッド名を覚えるのも大変です。どの機器に出力するにしても,文字列を出力するという点は同じですから,メソッド名も共通にできたほうが楽ですね。

 そこで,メソッド名をprintOutに決めてしまい,引数で出力機器を切り替えるようにしてみましょう(リスト2)。

public class Test_b {
  public static void printOut(String message, String device) {
    if(device.equals("ディスプレイ")) {
      System.out.println("ディスプレイに「" + message + "」と表示
      します");
    }
    else if(device.equals("プリンタ")) {
      System.out.println("「" + message + "」という文字列を印刷し
      ます");
    }
    else {
      System.out.println("その機器には対応していません");
    }
  }
  public static void main(String[] args) {
    String message = "日経ソフトウエア";
    printOut(message, "ディスプレイ");
    printOut(message, "プリンタ");
    printOut(message, "モデム");
  }
}
リスト2●リスト1を元に,出力機能を受け持つメソッドの名前をprintOutに統一したサンプル。2番目の引数で出力先を指定する

 printOutというメソッドに二つの引数を持たせて,二つ目の引数の値によって処理を変えています。こうすればメソッドは一つで済みますが,まだ問題があります。対応する機器を増やすたびに,printOutメソッドのコードを書き直さなければならないことです。すでに動いているコードを何度も書き直すと,どこかでバグを追加してしまうということも十分に考えられます。

 では,ポリモーフィズムを使ったコードを見てみましょう(リスト3)。

class Display {
  public void out(String message) {
    System.out.println("ディスプレイに「" + message + "」と表示
    します");
  }
}

class Printer {
  public void out(String message) {
      System.out.println("「" + message + "」という文字列を印刷
      します");
  }
}

public class Test_c {
  public static void main(String[] args) {
    String message = "日経ソフトウエア";
    Display display = new Display();
    Printer printer = new Printer();
    display.out(message);
    printer.out(message);
  }
}
リスト3●出力機器ごとにオブジェクトとメソッドをまとめた例。ポリモーフィズムを実現している