• ベストアンサー

オブジェクト・・・参照代入・・・???

問題(1) class ApBase extends Object implements Runnable (省略) ApBase aBase = new ApBase(); Runnable aR = aBase; ○ オブジェクトにインターフェースが実装されていることがわかる限りオブジェクト参照をインターフェイス参照に 代入することは可能です。 問題2 class ApBase extends Object implements Runnable (省略) Object obj = aBase; Runnable rn = obj; × コンパイラにとってobjはObjectなのでRunnnableインターフェイス参照への代入は認められません。 同じほんの問題です。 矛盾していませんか??? ・・・・多分僕の理解が足りないだけです(^_^;) もう少しわかりやすく教えてください・・・ お願いいたします

質問者が選んだベストアンサー

  • ベストアンサー
  • UKY
  • ベストアンサー率50% (604/1207)
回答No.1

ApBase クラスは、Object クラスを継承していて、Runnable インタフェイスを実装していますね。 これは、ApBase のインスタンスは Object のインスタンスとして扱うことができるし、また Runnable のインスタンスとして扱うことができるということです。ApBase のインスタンスは Object のインスタンスでもあり、また Runnable のインスタンスでもある、と考えてもかまいません。 ですから、ApBase 型の変数である aBase を Runnable 型の変数である aR に代入できるわけです。 では問題2ではどうかというと、Object はどのクラスも継承していませんし、どのインタフェイスも実装していません。従って、Object のインスタンスはあくまでも Object であって、ほかのクラスやインタフェースのインスタンスとして振る舞うことはできないのです。 なので、Object 型の変数である obj を Runnable 型の変数である rn に代入することはできません。 ここで注意しないといけないのは、コンパイラがチェックしているのは変数そのものの型であって、実際に変数に代入されている(実行時の)中身の型ではないことです。(変数の中身の型が問題となるのは、実行時にキャストをするときです) 仮に問題2で obj に代入されているインスタンスが実際には ApBase 型であっても、obj を rn に代入することはできません。 つまり、こういうことです。 ApBase 型変数 aBase には、ApBase のインスタンスしか代入できないので、aBase の値も当然 ApBase のインスタンスである。 すると、aBase を obj に代入しても、obj に実際に代入される値はやはり ApBase のインスタンスとなる。つまり、Object 型変数 obj に、ApBase のインスタンスが入っていることになる。 しかし、たとえ ApBase が Runnable を実装していても、obj を rn に代入することはできない。なぜなら、obj はあくまでも Object 型であり、Object のインスタンスとして振る舞うからだ。 (これでもやっぱりわかりづらいかな……)

azicyan
質問者

お礼

じっくり読ませていただきました。 extends object とかいてあって、紛らわしいけれども あくまでもObjectは 独立したインスタンス(ApBaseとは関係なく)を生成する、 ということでよろしいでしょうか・・・ (^_^;) 自信なしです・・・

azicyan
質問者

補足

いつもいつもありがとうございます。 ちょっと難しいので、今印刷しました。 じっくり読んでから、 お礼をいたします。

その他の回答 (2)

  • kakuto
  • ベストアンサー率25% (1/4)
回答No.3

ApBase クラスは Object クラスを継承し、Runnable インタフェースを実装しているので Object オブジェクトや Runnable オブジェクトとして扱うことはできますが、 Object クラスは Runnable インタフェースを実装していないため Object クラスの派生クラスが必ずしも Runnable インタフェースを実装しているとは限らないので Runnable オブジェクトとして扱うことはできません。

azicyan
質問者

お礼

ありがとうございます。 勉強になります

  • liar_adan
  • ベストアンサー率48% (730/1515)
回答No.2

問題2の場合は、代入を認めてもいいと思うかもしれませんが、 たとえば(作為的な例だけど)以下のような場合困ります。 -------------- class ApBase extends Object implements Runnable{ ... Object obj = aBase; String str = "abc"; if(...)obj = str; Runnable rn = obj; --------------- ここでは、if(...)の判断によって、 objにはApBase型が入ったり、String型が入ったりします。 ApBaseだったらいいのですが、 String型の場合、Runnableとしては使えません。 他の言語、たとえばSmalltalkというプログラミング言語では、 こういった代入が自由にできて、実際にメソッドを起動するときにエラーが出ます。 そういうのもひとつの方法ですが、エラーを検出しにくいという欠点があります。 問題2で代入したいときには、 Runnable rn = (Runnable)obj; のようにキャストします。 実際にRunnable型と互換性のない型だった場合、ここでエラーが出ます。 Javaでは、型のチェックを厳密にすることによって、 エラーが起こりにくいように、 また検出しやすいようにしているわけです。

azicyan
質問者

お礼

もし ObjにString型を代入した時にRunnableに代入できないので、 キャストしなければ代入を認めない。 という理解で正しいでしょうか・・

azicyan
質問者

補足

いつも助かっています。 ちょっと難しいので印刷してじっくり読ませていただきます。 後ほどお礼いたします。 ありがとうございます

関連するQ&A

専門家に質問してみよう