2017-08-30 3 views
1

Javaでは、オブジェクト参照が参照するインスタンスにどのように関連していますか ? 私は本当に面倒なことに遭遇し、それを深く理解したいと思っています。次のシナリオでは、サブクラスのshine()がスーパークラスのオーバーライド(通常)ですが、サブクラスでNEWが呼び出されたにもかかわらずスーパークラスの名前プロパティが使用されていますこれを理解します?継承シナリオでの参照とオブジェクトの関係

class Father { 
    public String name = "John Senior"; 
    public void shine() { 
     System.out.println(name + "'s shining"); 
    } 
} 

//Subclass 
class Son extends Father { 
    public String name = "John Junior"; 
    public void shine() { 
     System.out.println(name + "'s shining"); 
    } 
} 

//Demo Class 
class Test { 
    public static void main(String[] args) { 
     Father f1 = new Son(); 
     System.out.println(f1.name); 
     f1.shine(); 
    } 
} 

//program output 

/*John Senior 
John Junior's shining */ 
+2

このコードはコンパイルされません。メインには「s1」はありません。また、出力をポストする。 –

+0

@AbhijitSarkarあなたは正しいです。それはタイプミスでした。 – makassi

答えて

2

変数はJavaでは多態性ではありません。彼らはお互いを無効にしません。メソッドは多態性ですが。したがって、上記の動作。 スーパークラスメンバーを印刷する場合は、superキーワードを使用してください。

1

あなたが観察した振る舞いは最初は直感的ではないかもしれませんが、実際に言えば、@ shaggy-dで述べたように、変数は多相ではありません。私はちょっと説明しましょう、何が起こっているのですか?まず、shine()メソッドを忘れて、まずnameを理解させてください。ここで

はあなたmain法上のいくつかの他の例は、適切な出力と説明を、以下のとおりです。

例1:

public static void main(String[] args) { 
    Object f1 = new Son(); 
    System.out.println(Father.class.cast(f1).name); 
    System.out.println(Son.class.cast(f1).name); 
} 

が出力:

John Senior 
John Junior 

あなたが実際にタイプを隠しますf1変数のうち、Hi Java let's treat at within the scope asオブジェクト. So now when you want to get theの名前, you actually need to tell Java what it should think of the object, i.e., is it a父親or a息子. Depending on your decision, Java picks what名前 `属性を使用する。

例2:

public static void main(String[] args) { 
    Son f1 = new Son(); 
    System.out.println(Father.class.cast(f1).name); 
    System.out.println(Son.class.cast(f1).name); 
    System.out.println(f1.name); 
} 

出力:

John Senior 
John Junior 
John Junior 

オブジェクトがあなたの範囲内Sonとして扱われるべきであるというのJavaを伝える際に予想される、それは息子からnameを解決したよう(場合

今度はshine()メソッドに戻ります。@ shaggy-dと同様に、メソッドsは多形である。したがって、オブジェクトのメソッドを呼び出すとき、Javaはオブジェクト階層内で利用可能な「最も低い」実装を決定し、そのメソッドを実行します。

1

enter image description here

私はダイアグラムでそれを説明してみましょう:私たちはSonをインスタンス化するときにも、それが作成されて作成されたFatherのインスタンスがあります:ボンネットの下に、息子のコンストラクタが呼び出される前に - 父のコンストラクタも同様に呼び出されるため、新しいインスタンスSonには、それが拡張するクラスのオブジェクトのコンテキストもあります。あなたはf1.nameが評価されるタイプFather、としてF1を宣言したため、

さて、それはFatherのコンテキスト内で検索されている - それは我々が「先輩」取得している方法です。

しかし、このメソッドが呼び出されると、多形性が "キックイン"され、呼び出されるメソッドはSonに属し、Fatherのメソッドをオーバーライドします。これは、new Son()f1に割り当てたために発生しています。

+1

このきれいな説明をありがとう。私は、息子のインスタンスを作成するときはいつでも、父の引数なしのコンストラクタが暗黙のうちに呼び出されるという確認が欲しかった。 – makassi

関連する問題