2017-04-14 11 views
3

私はthisの答えを見ていました。なぜメソッドが多形であるのかフィールドではないのかという背後にある論理を理解できません。なぜJavaフィールドはポリモーフィックではありませんか?

デフォルトでは、すべてのメンバー関数はJavaで多態的です。つまり、 this.toString()を呼び出すと、Javaは動的バインディングを使用して 呼び出しを解決し、子バージョンを呼び出します。メンバーxにアクセスすると、 メンバーは現在のスコープ(父)のメンバーにアクセスします。メンバー はポリモフィックではないためです。

あなたは、スーパークラスとサブクラスの両方でいくつかのフィールドxを持っている、とあなたは、基本クラスで次のように呼び出したとき、あなたのサブクラスでtoStringを上書き:

System.out.println(this); //calls the subclass's toString implementation 
System.out.println(this.x) //prints the base class's x field 

の回答で、このための正当化最初にリンクされた質問に列挙されている質問には、基本クラスが独自のスコープ内にあるときにそのサブクラスについて「認識」していないが、ポリモーフィズムでは同じことだ。スーパークラスはサブクラスが存在するサブクラスメソッドは依然として呼び出されます。だから、Javaが正確に何をしているのでしょうか?サブクラスで動的バインディングを使用する方法と、スーパークラスのスコープを維持する方法の2つの方法が異なります。

編集:明確にするために、this.xが多態性と同じことをする理由につきまして、参照型だけでなくオブジェクトの実際の型を見て、xフィールドをサブクラスから印刷します。

+1

"クラスメンバー"は "フィールド"を意味しますか?もしそうなら、そうすることは明らかです。メソッドは「メンバー」です。 –

+0

@JonSkeet、ありがとうございます。直した。 – rb612

+0

しかし、アクセサは多相であるため、ゲッターを使用すると、必要な動作を実現できます。 –

答えて

1

サブタイプの多型性を達成するには、Javaではどのメソッドを呼び出すかを追跡する必要があり、追加のオーバーヘッドが必要です。フィールドを非公開にし、getterを使用することで、多種多様なフィールドを実現できます(前者は必須ではありませんが、賢明です)。あなたはINVOKEVIRTUAL

通話

  • invokestatic
  • invokespecial
  • invokeinterface
  • +0

    ありがとう!なぜメソッドが多態性であり、フィールドではないのか、より興味があります。 – rb612

    +0

    私は下線を引かなければならないと思う*追加のオーバーヘッド* :)が必要です。あなたの質問を逆にすることから始めましょう。なぜフィールドにアクセスするには多態性のメカニズムが必要でしょうか?メソッドに関しては、サブタイプ多型がOOP世界における機能拡張の基本的メカニズムの1つであると主張することによって正当化され得る。では、プライベートではないメソッドに対してinvokevirtual(デフォルトのものとは異なる:現在のオブジェクトのメソッドにアクセスすること)の機能を追加し、そのようなメソッドを呼び出す間にオーバーヘッドを受け入れましょう。必要なときにセッター/ゲッターを得ることができる一方で、我々はすべてのフィールド解決のためにそのようなオーバーヘッドを受け入れるべきですか? –

    関連する問題