1

サンプルのポリモーフィズムの概念を説明する次のサンプルコードがあります-オーバーライド

    クラススーパー
    {
        public int 番号 = 1;
        public char superText='a';
        public String getColor()
        {
            「赤」を返します。
        }
    }

    クラスサブはスーパーを拡張します
    {
        public int 番号 = 2;
        public char subText='b';

        public String getColor()
        {
            「青」を返します。
        }
    }


    公開クラス Sample2
    {
        public static void main(String[] args)
        {
            スーパースーパーサブ = 新しいサブ ();
            System.out.println( supersub.getColor() + supersub.number + supersub.superText );
        }



    }

出力は blue1 です。

質問1:

派生クラス getColor() の Method がオーバーライドされ、Super クラスの Field が表示されます。

派生クラスの数値フィールドが呼び出されない理由を説明できますか? つまり、出力は blue2 です


質問 2: *メモリ割り当てについて*

以下のオブジェクトのインスタンス化のために、

   Sub subobj = new Sub();
フィールド 'number' のメモリがヒープに割り当てられ、Number 変数のアドレスがオブジェクト参照 subobj に割り当てられます。

以下のケースを検討してください。

スーパースーパーサブ = 新しいサブ ();

(a)ここで、派生クラス「Sub」の変数「number and subText」のメモリが作成され、変数のアドレスがスーパーサブ オブジェクトに配置されます。

アクセスすると、supersub.subText で subText が解決できないというエラーが出ました。

SO, PLAIN POINT (a)上記の (a) すなわち、Derive Class 変数のメモリ割り当て

ありがとう、サイボーグズ

4

5 に答える 5

2

Java のフィールドは呼び出されず、動的ディスパッチ/ランタイム ポリモーフィズムの影響を受けません。あなたの場合、実際には、たまたま同じ名前を持つ 2 つの別々のフィールドがあります:Super#numberSub#number. Subクラスは継承するSuper#numberため、両方を持ち、どちらにアクセスするかは、アクセスする変数の静的なコンパイル時の型によって異なります。subobjこれは、一方と他方にアクセスする理由を説明しsuperobjています。

于 2013-02-12T14:36:51.320 に答える
2

派生クラスの数値フィールドが呼び出されない理由を説明できますか?

これfieldsは、ポリモーフィックではないためです。特定の参照のフィールドにアクセスすると、参照型で定義されたフィールドにアクセスでき、決定は実際のオブジェクト型に基づいていません。

フィールド 'number' のメモリがヒープに割り当てられ、Number 変数のアドレスがオブジェクト参照 subobj に割り当てられます。

いいえnumberプリミティブ型intであり、プリミティブはヒープに割り当てられません。それらはリテラル プールに格納されます。プリミティブとラッパー クラスは 2 つの異なるものです。Integerの代わりに使用していた場合、値が範囲内にない場合、リテラル プールによってキャッシュされるintオブジェクトを に作成したことになります。HeapJava

supersub.subText subText を解決できないというエラーが発生しました。

これは、最初の疑問の説明から推測できます。フィールド アクセスは、実際のオブジェクト タイプではなく、参照タイプに基づいて解決されるためです。したがって、そのフィールドはサブクラスではなく、そのクラスの一部ではないため、明らかに参照にアクセスsubTextすることはできません。Super

于 2013-02-12T14:37:03.430 に答える
2

質問1:

メソッドは派生クラスが表示され、スーパークラスのフィールドが表示されます。

派生クラスの数値フィールドが呼び出されない理由を説明できますか? つまり、出力は blue2 です

フィールドはオーバーライドできません。2 つのクラスが親子関係を共有している場合でも、継承されたフィールドと名前を共有している場合でも、フィールドは定義されたクラスに属します。つまり、numberinは inSubとはまったく別の分野numberですSuper

質問 2: ここで変数用のメモリ、派生クラス 'Sub' の 'number and subText' が作成され、変数のアドレスが supersub オブジェクトに配置されます。

に格納されているオブジェクトsupersubの型Subは ですが、コンパイラはそれを認識していません。

Java は静的に型付けされた言語であるため、コンパイラは参照の宣言された型 (つまり、変数の型) を使用します。これは、実際のほとんどの場合、実行時の型 (式で明らかな型) が定義されてnewいないためです。コンパイル時に必ず認識されます。たとえば、別のメソッドから、または 2 つまたは 3 つの候補メソッドからこのオブジェクトを取得した可能性があるため、実行時の型は予測できません。

Super参照をスーパークラス変数に格納するということは、そのオブジェクトをしばらく使用するつもりであることを意味します。次に、コンパイラは、この認識された意図に基づいて動作します。Superの実行時型のインスタンスのみを持つことは保証されてSubいないため、期待どおりの仮定を行うことはできません。

そうは言っても、参照を何らかの種類の変数に格納しても、オブジェクトは変更されません。オブジェクトを、アクセスしようとしているメンバー (あなたの場合はSub型) を実際に認識している型の変数にキャストし直した場合、それらがまだそこにあることがわかります (そして、それらは保持されます)。値)。

于 2013-02-12T14:41:03.400 に答える
0

単純に、フィールドをオーバーライドできないためです。オーバーライドできるのはメソッドだけです。

于 2013-02-12T14:36:36.863 に答える
0

Java ではクラス変数をオーバーライドしません。それらを非表示にします。オーバーライドは、インスタンス メソッドです。

于 2013-02-12T14:37:13.197 に答える