- ベストアンサー
継承について - メンバの型と考え方の法則
- 継承において、フィールドの型やメソッドの実行結果の型は、その変数やオブジェクトの型ではなく、宣言された型(親クラス)に従うという法則があります。
- 問題1では、親クラスのフィールドとメソッドをサブクラスが継承しています。そこで、変数の型に従ってdの値が10になり、メソッドの実行結果の型に従ってdの値が20.0になります。
- 問題2では、親クラスとサブクラスのフィールドとメソッドが両方ともstatic(クラス変数やクラスメソッド)となっています。そのため、変数dやメソッドmethは親クラスのものが使用され、結果として10が出力されます。
- みんなの回答 (1)
- 専門家の回答
質問者が選んだベストアンサー
う~~ん、これってなかなか難しいですよね。 こういう動作をするように(JAVAでは)なってるとしか言いようがないような気がしますが、一応説明を試みてみます。 今スーパークラスと、そのサブクラスがあって、 同じフィールド名、同じメソッド名があるとすると、 サブクラスでは、上位クラスのフィールドやメソッドはオーバーライド(上書)されて、それぞれのクラスのモノが使われるというのは良いですよね。 今問題となっているのは、スーパークラスの変数にサブクラスの変数を入れた場合どうなるか? ということなんですが、 スーパークラスからは、スーパークラスのメソッドやフィールドにしかアクセスできないというのは良いですか? このルールで言うと、例外となるのは、質問文の問題でいうと、インスタンスメソッドがスーパークラスに代入(やキャスト)したのに、どうして、スーパークラスのメソッドが使われないで、サブクラス自身のメソッドが使われるのかということですね。 言語の実装としては、スーパークラスのメソッドが使われるような実装もありだと思いますが、そのようになっていないのは、スーパークラス変数にサブクラスの変数を代入して使うということがどういうこと(どういうことであって欲しい)かということだと思います。 スーパークラスの変数には、その配下となるさまざまなサブクラスの変数を代入できますが、そのようにするのは、それぞれのサブクラスをまとめて扱いたいからです。その時に、せっかくそれぞれの特殊化したメソッドでなくて、スーパークラスのメソッドしか使われないのであれば、何をやってんだかわからないです。つまり、変数に対して同じメソッドを使って、それぞれの特殊化した(サブクラスで定義された)メソッドを使って欲しいわけです。 まあ、そういうわけで、スーパークラス変数に代入したサブクラス変数のインスタンスメソッドが呼ばれます。 staticメソッドについては、staticメソッドは、インスタンスから呼び出しができますが、インスタンスが無くても呼び出せるクラスに固有のメソッドです。(クラスメソッド)なので、そのクラスのメソッドが呼び出されるのは、妥当です。
お礼
BLUEPIXYさん、いつもありがとうございます。 >そのようになっていないのは、スーパークラス変数にサブクラスの変数を代入して使うということがどういうこと(どういうことであって欲しい)かということだと思います。 このような考え方が私には出来ていませんでした。たしかにその通りですね。 書いていただいた事を何回も読み返してようやく理解できるようになりました。何だか喉の痞えが取れた気がします。 単なるJavaの決め事として丸暗記するのではなく、理由を納得できてよかったです。 まだSJC-P試験勉強の序盤戦。 今後もまだまだ???という部分に出会い、質問させていただくかもしれませんが、よろしくお願いします。