JavaA2Z

KAB-studio > プログラミング > JavaA2Z > ポリモーフィズムとは

ポリモーフィズム

日本語 多態性、多相性
英語 polymorphism
ふりがな ぽりもーふぃずむ
フリガナ ポリモーフィズム

解説

サブクラス参照スーパークラス参照変数に格納できる機能。
 
あるクラスインスタンスを作成した時に返される、そのインスタンスへの参照は、そのクラススーパークラス参照変数にも格納することができる。
この「サブクラス参照からスーパークラス参照への変換」は「アップキャスト」と呼ばれ、明示的キャストを必要としない。
この変換時に、インスタンスそのものには全く変化は起こらない点に注意。つまり「参照の入れ物」が変わっただけで、インスタンスは作った時のクラスそのままである。
 
格納する参照スーパークラスにすることで、プログラムの見た目上は「スーパークラスメソッド」が呼ばれるように見える。
だが、「オーバーライド」されているメソッドがある場合、メソッドは「インスタンスを作成した時点でのメソッド」が呼ばれるため、実際に呼ばれるのは「スーパークラスメソッド」ではなく「インスタンスを作成したクラスメソッド」ということになる。
この機能により、特にメソッド引数スーパークラス参照変数を持つ場合、その参照変数に格納されているのが「スーパークラスインスタンスへの参照」か「サブクラスインスタンスへの参照」かはプログラム上ではわからない。
 
スーパークラス参照を使用していても、実際には「どのクラスのどのメソッドが呼ばれる」のかはわからない。そのため、同じスーパークラス参照を使用しても、実際のインスタンスによって振る舞い・結果が異なるということを意味する。
これは、スーパークラスを扱う側は「インスタンスがどのクラスかを考えるべきではない」ことを意味する。スーパークラスが持つメソッド・ルールを守って使用するだけで、その結果、様々な結果が返されても問題ないようにプログラムを組むべきである。
また逆に、サブクラスを作りオーバーライドする場合には、スーパークラスの「オーバーライドされるメソッド」の結果を大きく逸脱しない結果を返さなければならない。この決まりを守らなければ、スーパークラス引数に持つメソッドサブクラスを渡して、そのメソッド内でオーバーライドしたメソッドが呼ばれた場合に、望む結果(=スーパークラスメソッドが返すのに近い結果)が返らず、うまく動かない場合がある。
 
「ポリモーフィズム」という言葉は、「ポリ-モーフィズム(poly-morphism)」と分け、「ポリ」は「ポリゴン」の「ポリ」=「多」、「モーフィズム」は「モーフィング」という言葉でおなじみ「姿形を変える」、つまりポリモーフィズムとは「様々な姿を見せる」という意味となる。
スーパークラスが実際には様々なサブクラスとして振る舞う、これこそがポリモーフィズムの意味である。

参考サイト


(KAB-studioからのおしらせです)

サンプルプログラム(とか)サンプルを別ウィンドウで表示サンプルをクリップボードへコピー(WindowsでIEの場合のみ)

// Sample.java
public class Sample
{
    public static void main( String[] args )
    {
        // Stringクラスのインスタンスを作り、
        // Objectクラスの参照型変数に格納します。
        Object object = new String( "A" );
        // ObjectクラスはStringクラスのスーパークラスなので、
        // アップキャストに当たるので何もせずに代入できます。
        // この際、ただ単に「参照値が代入される」だけで、
        // Stringクラスのインスタンスは何も変化しません。
        // ただ単に「参照値を入れる器が変わっただけ」です。
        
        System.out.println( object.hashCode() );
        // 65
        // Object#hashCode()メソッドは「インスタンスの参照の値」を返しますが、
        // String#hashCode()メソッドでオーバーライドされているため、
        // 「文字列を元にして作られたハッシュコード」が返されます。
        // つまり、見た目としてはObjectクラスですが、実際の振る舞いは
        // Stringクラスということです。
    }

    /**
    *   メソッドの引数でポリモーフィズムを利用する場合。
    */
    private void printHashCode( Object object )
    {
        // 引数にObject型を使用しているため、
        // すべてのクラスが引数として渡せます。
        System.out.println( object.hashCode() );
        // つまり、このhashCode()メソッドが、実際にはどの
        // クラスのhashCode()メソッドを呼び出すのか、
        // 全くわからないということです。
        // そのため、多くのサブクラスを持つクラスを
        // 引数に使う場合には「実際のクラスを限定できない」
        // ことを踏まえる必要があります。
        // また、サブクラスを作りオーバーライドをするということは
        // このような理由から「スーパークラスの振る舞いを
        // 踏襲した結果」を返すようにしなければならないという
        // ことです。
    }
}
// Sample.java
public class Sample
{
    public static void main( String[] args )
    {
        // Stringクラスのインスタンスを作り、
        // Objectクラスの参照型変数に格納します。
        Object object = new String( "A" );
        // ObjectクラスはStringクラスのスーパークラスなので、
        // アップキャストに当たるので何もせずに代入できます。
        // この際、ただ単に「参照値が代入される」だけで、
        // Stringクラスのインスタンスは何も変化しません。
        // ただ単に「参照値を入れる器が変わっただけ」です。
        
        System.out.println( object.hashCode() );
        // 65
        // Object#hashCode()メソッドは「インスタンスの参照の値」を返しますが、
        // String#hashCode()メソッドでオーバーライドされているため、
        // 「文字列を元にして作られたハッシュコード」が返されます。
        // つまり、見た目としてはObjectクラスですが、実際の振る舞いは
        // Stringクラスということです。
    }

    /**
    *   メソッドの引数でポリモーフィズムを利用する場合。
    */
    private void printHashCode( Object object )
    {
        // 引数にObject型を使用しているため、
        // すべてのクラスが引数として渡せます。
        System.out.println( object.hashCode() );
        // つまり、このhashCode()メソッドが、実際にはどの
        // クラスのhashCode()メソッドを呼び出すのか、
        // 全くわからないということです。
        // そのため、多くのサブクラスを持つクラスを
        // 引数に使う場合には「実際のクラスを限定できない」
        // ことを踏まえる必要があります。
        // また、サブクラスを作りオーバーライドをするということは
        // このような理由から「スーパークラスの振る舞いを
        // 踏襲した結果」を返すようにしなければならないという
        // ことです。
    }
}

この単語を含むページ

「みだし」に含まれているページ

はてなブックマーク 詳細を表示 はてなブックマーク ブックマーク数
livedoorクリップ 詳細を表示 livedoorクリップ ブックマーク数
Yahoo!ブックマーク 詳細を表示 users
del.icio.us 登録する RSSに登録
サンプルを別ウィンドウで表示
サンプルをクリップボードへコピー(WindowsでIEの場合のみ)
update:2005/05/23
このページは、Javaプログラミング言語についての用語を網羅した辞書「JavaA2Z」の一ページです。
詳しくは「JavaA2Z」表紙の説明をご覧ください。