1

Javaはオブジェクト指向プログラミング言語です。継承は最も重要な機能の1つです。オブジェクトの状態を非表示にするためにカプセル化を使用します。以下のプログラムでは、年齢とカウンターにプライベートアクセス修飾子を使用する必要がありましたが、この継承をテストするためにパブリックを使用しました。

  1. オブジェクトの状態に直接アクセスする場合(プリミティブ型またはオブジェクト参照)に継承が機能しない理由。SOP3の出力が予想と異なります。
  2. コンパイラはSOP13行とSOP14行でエラーを出さないため。なぜFatherクラスの詳細が子クラスではなく出力されるのか。

public class Father {

    public int age = 50;
    /*
     * Counter keeps track of total no of instances created so far.
     */
    public static int counter = 0;

    public Father(){
        super();
        synchronized (Father.class) {
            ++Father.counter;   
        }
    }

    public int getAge(){
        return this.age;
    }

    public static int getStaticCount(){
        return Father.counter;
    }

}

public class Child extends Father {

    public int age = 25;
    public static int counter = 0;

    public Child(){
        super();
        synchronized (Child.class) {
            ++Child.counter;    
        }
    }

    public int getAge(){
        return this.age;
    }

    public static int getStaticCount(){
        return Child.counter;
    }

    public static void main(String args[]){

        Father father = new Father();
        Father child = new Child();
        Child realChild = new Child();

        System.out.println("Expecting Father Class details to be printed");
        System.out.println("SOP 1 : Father Age : "+father.age);     //prints 50 as expected.
        System.out.println("SOP 2 : Father Age : "+father.getAge());//prints 50 as expected.

        System.out.println("Expecting Child Class details to be printed");
        /*
         * Why inheritance does not work in case of direct integer access.
         */
        System.out.println("SOP 3 : Child Age : "+child.age); //prints 50 ?? , Father Age . Why ?
        System.out.println("SOP 4 : Child Age : "+child.getAge());//prints 25 as expected.

        System.out.println("Expecting Child Class details to be printed");
        System.out.println("SOP 5 : Child Age : "+realChild.age); //prints 25 as expected.
        System.out.println("SOP 6 : Child Age : "+realChild.getAge());//prints 25 as expected.

        /*
         *Total No of static Count : proper way of accessing static field using Class Name. 
         */
        System.out.println("SOP 7 : Father Instance Count : Using Class Reference :"+Father.counter);
        System.out.println("SOP 8 : Father Instance Count : Using Class Reference :"+Father.getStaticCount());

        /*
         * Incorrect Way to use static. Since Compiler allows this lets see output.
         */

        System.out.println("SOP 9 : Father Instance Count : Using Object Reference :"+father.counter); //prints 3 as expected.
        System.out.println("SOP 10 : Father Instance Count : Using Object Reference :"+father.getStaticCount());//prints 3 as expected.

        /*
         *Total No of static Count : proper way of accessing static field using Class Name.  
         */
        System.out.println("SOP 11 : Child Instance Count : Using Class Reference :"+Child.counter); // output is 2 as expected
        System.out.println("SOP 12 : Child Instance Count : Using Class Reference :"+Child.getStaticCount()); // output is 2 as expected

        /*
         * Incorrect Way to use static.Since Compiler allows this lets see output.
         * This invokes function of parent class. Why ? Inheritance does not work for static fields.
         */
        System.out.println("SOP 13 : child Instance Count : Using Object Reference :"+child.counter); // output is 3 but expected is 2 .          why ? 
        System.out.println("SOP 14 : child Instance Count : Using Object Reference :"+child.getStaticCount()); // output is 3 but expected is 2 .  why ?

        /*
         * Incorrect Way to use static.Since Compiler allows this lets see output.
         * This invokes function of parent class. Why ?
         */
        System.out.println("SOP 15 : child Instance Count : Using Object Reference :"+realChild.counter); // output is 2 as expected
        System.out.println("SOP 16 : child Instance Count : Using Object Reference :"+realChild.getStaticCount()); // output is 2 as expected
    }

}

私の質問は、継承がインスタンスメソッドに対してのみ機能する理由です。SOP 3、SOP 13、SOP14で出力が異なる理由。

4

4 に答える 4

3

その理由は、ポリモーフィズムがインスタンス変数に適用されないためです。あなたがしているのは可変シャドウイングです。

SOP 3および4では、子クラスの同じ名前の変数が基本クラスの変数をシャドウイングします。また、これはコンパイル時に解決されるため、静的型の値が選択されます。

SOP13とSOP14では、これは同じ理由で発生します。メソッドのスコープでは、子のクラス非表示変数は不明です。

JSLから:

クラス型C(§8.1.6)で宣言された、またはクラス型C(§8.1.6)によって継承されたメンバーmの宣言のスコープは、ネストされた型宣言を含むCの本体全体です。

于 2012-09-15T20:34:05.290 に答える
1

("SOP 3 : Child Age : "+child.age);

のようなものはありません"overriding fields"。フィールドをシャドウすることはできますが、オーバーライドすることはできません。 Fields aren't polymorphic。詳細については、セクション6.4.1 of the Java Language Specificationを参照してください。

///// --------------質問の終わり:1 ------------------- /////

("SO 13 : child Instance Count : Using Object Reference :"+child.counter);

child.counter私がその前に述べたように、static counter variableのクラスで指しているFields are not Polymorphic

///// --------------質問の終わり:2 ------------------- /////

("SOP 14 : child Instance Count : Using Object Reference :"+child.getStaticCount());

child.getStaticCount()クラスの父static counter variableを指しています、

で試してみてくださいrealChild結果は、予想どおり、子クラスstatic counter variableのを指しているため、2になります。

System.out.println("SOP 14 : child Instance Count : Using Object Reference :"+realChild.getStaticCount());

于 2012-09-15T20:39:49.390 に答える
0
System.out.println("SOP 3 : Child Age : "+child.age);
System.out.println("SOP 13 : child Instance Count : Using Object Reference :"+child.counter); // output is 3 but expected is 2 .          why ? 
System.out.println("SOP 14 : child Instance Count : Using Object Reference :"+child.getStaticCount()); // output is 3 but expected is 2 .  why ?

上記の例では、子クラスのオブジェクトを作成Father child = new Child();し、これを子のスーパークラスである父クラス参照変数に格納します。メソッドを呼び出そうとしたり、「子」参照変数によってインスタンス変数にアクセスしようとしたりする場合は、最初にスーパークラスでチェックインし、次にスーパークラスで見つかった場合はサブクラスにアクセスして実行されます。

于 2012-09-15T21:16:23.413 に答える
0

コンパイラがSOP3の行を調べているとき、インスタンスchild以外のものが含まれていることはわかりませんFather...サブクラスをその中に入れたという事実は関係ありません。コンパイラは、に基づいてフィールドルックアップをバインドします。これはクラスです...したがって、整数フィールドFatherにアクセスするため、期待される出力は25ではなく50になります。Father.age

SOP13はSOP3の場合と同じです...唯一の違いは、インスタンス変数を介して静的フィールドにアクセスしていることです...これは、混乱を引き起こす可能性があるため、悪いスタイルと見なされます。

SOP 14は、インスタンスを介して静的メソッドにアクセスしています...また、変数はクラスのオブジェクトを保持してFatherいるため、Father.getStaticCount()返されます。繰り返しますが、これは悪いスタイルです。

にアクセスすること((Father)realChild).ageで同様の効果を得ることができます。いずれの場合も、クラスのフィールド/メソッドが必要であることを指定しています。Father.counterFather.getStaticCountFather

これは、Javaにフィールドのオーバーロードがなく、静的メソッドもオーバーロードされていないためです。

子クラス内から親フィールドにアクセスする場合は、親クラスへのキャストを呼び出す必要があります。

于 2012-09-15T20:51:02.710 に答える