2017-05-06 14 views
0

私は以下の4つのクラスを持っています。サブクラスのこの型変換された変数呼び出し関数はなぜですか?

クラス注:

public class Note { 

    Pitch primaryPitch = new Pitch(); 
    static Pitch secondaryPitch = new Pitch(); 

    Note() { 
     System.out.println("Tune()"); 
    } 
    static void pitch() { 
     System.out.println("Note.pitch()"); 
    } 
    void volume() { 
     System.out.println("Note.volume()"); 
    } 
} 

クラスチューン:

public class Tune extends Note{ 

    Tune() { 
     System.out.println("Tune()"); 
    } 

    static void pitch() { 
     System.out.println("Tune.pitch()"); 
    } 

    void volume() { 
     System.out.println("Tune.volume()"); 
    } 

    void rhythm() 
    { 
     Note note = (Note) this; 
     note.volume(); 
    } 
} 

クラスの歌:

public class Song extends Tune{ 

    void volume() { 
     System.out.println("Song.volume()"); 
     } 
    } 

クラスTest:

public class Test { 

    public static void main(String[] args) { 

      Note note2 = new Song(); 
      ((Tune)note2).rhythm(); 
} 

mainを実行すると、出力はNote.volume()となります。その理由は私がnote.volume();を呼び出すとTuneクラスでノートがメモオブジェクトに型キャストされているので、メモクラスのvolume()メソッド呼び出しを使用することが期待されるためです。代わりに、Song.volume()を取得します。これは、Songクラスのvolume()メソッド呼び出しを使用していることを意味します。

私の質問は、なぜSong.volume()で、note.volume();ではないのですか?

+4

あなたは、あなたがポリモーフィズムについて学ぶ必要があり、まだの場合その行動。 – 4castle

+0

'' Song'は 'volume'をオーバーロードし、それはオーバーライドの仕組みです。ポインタ式のコンパイル時の型ではなく、実際の実行時型のインプリメンテーションを多相的に呼び出します。 –

答えて

3

noteは、タイプSong()のオブジェクトです。あなたが親の型にキャストしたという事実は、volume()メソッドの多態的な動作を変更しません。これは、あなたのIDEでコードを実行した場合明らかである、とTune.Rhythm()で、変数の値を見て:それは説明しているので

enter image description here

1

thisは、現在は、あなたがNoteにキャストしても、それは実行時にそうcast、ランタイムでは、Javaのが型を持っていない、ところでまだSongインスタンス

インスタンスSong意味します無意味です。 castは文脈によってタイプを推論するちょうどCompilerです。

Tune、 とOverridevolume方法からextendsによってNoteからもSongextendsので、そうthis.volume()OverrideSong.volumeメソッドを呼び出します。

など、volume方法でsuperを使用する必要がある、parentクラスNote.volumeを呼び出す必要がある場合:super.volume()

関連する問題