2013-02-18 13 views
9

私はJavaを学んでいます。私は相続に疑念があります。子クラスが親クラスを継承し、親クラスが親クラスで宣言されたインスタンス変数を参照するメソッドを持つ場合。しかし、子クラスdintはこのメソッドをオーバーライドし、親と同じ名前のインスタンス変数を宣言しています。この場合、子からのインスタンス変数が参照されるか、親が参照されます。以下のコードスニペットがあるインスタンス変数をオーバーライドするJava継承

class parent { 
    int a; 
    parent() { 
     System.out.println("in parent"); 
     a = 10; 
    } 
    void method() { 
     System.out.println(a); 
    } 
} 
class child extends parent { 
    int a; 
    child() { 
     System.out.println("in child"); 
     a = 11; 
    } 
} 

public class Test { 
    public static void main(String args[]) throws IOException { 
     parent p1 = new child(); 
     p1.method(); 
    } 
} 

私が手出力が親に

ある

は、誰かが私を理解してくださいすることができた子で
なぜその参照親クラスのインスタンス変数aと子クラスのaではありません。

もう一つの疑問は、親と子のクラスに静的メソッドがあり、同じシグネチャを持つ静的メソッドも宣言されている場合、メソッドを隠すことを理解していたことです。ここに隠れているの?どんな方法が隠されていますか?その親の方法が私に説明できたらどうですか?
ありがとうございます。

+2

あなたのコードはコンパイルされていますか?コードを実行しましたか? –

+1

これはコンパイルしないでください、親にはメソッド 'method()'がありません –

+0

誤ってフォーマットされました。今すぐコードを更新しました。 – Mojoy

答えて

17
  1. Javaインスタンス変数は、サブクラスでオーバーライドすることはできません。 Javaの継承はそのようには機能しません。

  2. この例では、処理を隠す(またはオーバーライドまたはオーバーロードする)方法はありません。

  3. しかし、インスタンス変数が隠れています。クラスchildにおいて、aの宣言は、parentaの宣言を隠し、そしてchildクラスのaへのすべての参照はchild.aないparent.aを指します。これを実行してみて、より分かりやすくこれを説明するために

public static void main(String args[]) throws IOException { 
    child c1 = new child(); 
    parent p1 = c1; 

    System.out.println("p1.a is " + p1.a); 
    System.out.println("c1.a is " + c1.a); 
    System.out.println("p1 == c1 is " + (p1 == c1)); 
} 

それはすべき出力:

p1.a is 10 
    c1.a is 11 
    p1 == c1 is true 

これはaと呼ばれる2つの異なるフィールドを持つ一つのオブジェクトがあることを示しています。..アクセスが許可されていれば、両方の値を保持することができます。


最後に、標準のJava識別子の規則に従うことを学ぶ必要があります。クラス名は常に大文字で始まる必要があります。

2

Instance variables are not overriden in sub-class。スーパークラスと同じ名前の変数をクラス内に定義すると、という変数のシャドウイングinheretence and polymorphismはインスタンス変数には適用されません。 parentでmethod()を定義し、それをChildクラスでオーバーライドする場合以下)(子供のメソッドを呼び出します

parent p1 = new child(); 
  1. を印刷による実行時の多型は、親でスーパー()呼び出しの呼び出しの親のコンストラクタ
  2. 印刷の」と子コンストラクタ
  3. を呼び出します親のaを1
  4. の子を印刷して初期化し、Chils aを11に初期化する。

    p1.method();// this invokes Child's method() during run-time 
    
0

問題は、子インスタンスを作成し、それを親の参照に格納することです。したがって、オブジェクトのプロパティにアクセスするとき、JVMは親の変数値を参照します。

子クラスの参照変数であった場合、子クラスの変数値を受け取ることになります。

上記はJavaの機能です。

0

親のインスタンスを作成するとき。そのため、実行時にコンパイラは親オブジェクトを呼び出す 以下のコードを試してください。

public static void main(String args[]) throws IOException { 
    child c1 = new child(); 
    c1.method(); 
} 
1

あなたはこの

親P1 =新しい子を(行います)。 JVMは何をすべきか

はその後

   first Initialize Parent() 

         || 

       second Initialize Child() 

ので、まず親コンストラクタが呼び出されると、子どものですが、p1は、子供のオブジェクトを参照しているため、出力値は、11となります。声明、

parent p1 = new child(); 

が)(、メソッドの親バージョンを実行している実行され、親クラスに知られている唯一の値は子クラスで

1

あなたがメソッドをオーバーライドしていないと()、それ自身。したがって、a = 10を出力します(その時点でスタック上にあるので)。

最後に、変数aを親クラスから子クラスにシャドウするだけです。