11

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

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();
    }
}

私が得る出力は


で子で
10

a誰かが、子クラスではなく親クラスのインスタンス変数を参照している理由を理解してもらえますかa

もう1つの疑問は、親クラスに静的メソッドがあり、子クラスも同じシグネチャを持つ静的メソッドを宣言している場合に、メソッドを非表示にすることを理解したことです。ここで隠すということは?どのメソッドが隠されていますか?親メソッドの場合、説明していただけますか?
前もって感謝します。

4

6 に答える 6

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

  2. あなたの例では、メソッドを非表示にする(またはオーバーライドまたはオーバーロードする)ことはありません。

  3. ただし、インスタンス変数の非表示があります。クラスchildでは、の宣言はinaの宣言を非表示にし、クラス内のすべての参照はではなくを参照します。aparentachildchild.aparent.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

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


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

于 2013-02-18T10:05:29.353 に答える
2

Instance variables are not overriden in sub-class。スーパークラスと同じ名前でクラスに変数を定義する場合、変数のシャドウイング inheritance and polymorphismと呼ばれるものはインスタンス変数には適用されません。親でmethod()を定義し、Childクラスでオーバーライドする場合。以下は、実行時のポリモーフィズム印刷のために子のmethod()を呼び出します11

 parent p1 = new child();
  1. 子コンストラクターを呼び出します
  2. super()呼び出しでinvokeの親のコンストラクター
  3. の「親内」を印刷し、親のaを10に初期化します
  4. 子に印刷し、子aを11に初期化します

        p1.method();// this invokes Child's method() during run-time
    
于 2013-02-18T10:04:52.117 に答える
1

あなたがこれをするとき

親P1=new Child();

JVMが行うことは

               first  Initialize Parent()

                         ||

               second Initialize Child()

したがって、最初に親コンストラクターが呼び出され、次に子のコンストラクターが呼び出されますが、p1は子のオブジェクトを参照しているため、出力値は11になります。

于 2013-02-18T10:11:17.310 に答える
1

子クラスでmethod()をオーバーライドしていないため、ステートメントの場合、

parent p1 = new child();

が実行され、method()の親バージョンが実行され、親クラスに認識されている値はそれ自体のaのみです。したがって、a = 10を出力します(その時点でスタック上にあるため)。

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

于 2013-02-18T10:16:38.397 に答える
0

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

子クラスの参照変数である場合は、子クラスの変数値を受け取ります。

上記はJavaの機能です。

于 2013-02-18T10:05:54.380 に答える
0

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

public static void main(String args[]) throws IOException {
    child c1 = new child();
    c1.method();
}
于 2013-02-18T10:08:01.600 に答える