• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:ポリモーフィズムについて考えている途中、思ったことがありまして)

ポリモーフィズムについての疑問

このQ&Aのポイント
  • ポリモーフィズムの考え方として、「インスタンスは親クラスの型を持つ変数に代入できる」ですが、Student student = new Student();も同じような動きとなる?と思います。
  • なぜ、Student student = new Student();というように宣言しなければいけないのか理由があるのか疑問です。
  • 説明が分かりにくくなっているのかもしれませんが、ポリモーフィズムの考え方についてのヒントがほしいです。

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

  • ベストアンサー
  • salsberry
  • ベストアンサー率69% (495/711)
回答No.1

> student = new Student(); > として宣言できても良いように思います。 変数studentの型を宣言しなくてもいいじゃないかということでしょうか。 Javaでは許されていませんが、変数の型を宣言しなくていい言語もあります。 クラスPersonがメソッドm()、Studentがm()とn()を持っているとした場合、 Student student = new Student(); student.n(); は問題ありませんが、 Person student = new Student(); student.n(); はJavaではコンパイル時エラーになります。Personにはn()がないからです。n()を呼ぶためには一度Studentにキャストする必要があります。 変数に型宣言がない言語ではコンパイル時にエラーにならず、実行時に型チェック (このオブジェクトはn()というメソッドを持っているか?) を行うことになります。その分だけ、変数型宣言のある言語よりも実行速度が低下するリスクがあります。 変数型宣言があるほうが、コンパイル時に型エラーを発見しやすいというメリットもあります。

kensiroooo
質問者

お礼

ありがとうございます。 なるほど、オブジェクト指向を意識しているために、 型宣言時に課しているということですね。 確かに、そのほうがコンパイル時に間違いを見つけやすいと 考えることができますね。 実行時に考える手間よりも、実装時に型宣言を 意識した作りとなっているという意味ですか。 とても理解が深まりました。助かりました。

その他の回答 (3)

  • hoge_piyo
  • ベストアンサー率57% (15/26)
回答No.4

>m()は、Studentのm()でしょうか? Studentクラスで定義しなおした(つまりオーバーロードした)ならば、Studentクラスのメソッドが呼ばれます。 >親クラスで子クラスのメソッドをすべて宣言しておけば、ますます型を宣言した代入方法はいらない 確かにその場合は、メソッドを呼ぶと言う点に関しては、同じ事になります。ただし、親クラスを作る人と子クラスを作る人が違う場合などは、子クラスでメソッドを増やすことを禁止することができません。 また、実際にやることが同じだとしても、 Person student = new Student(); という場合は 「この変数の中身はStudent型だけれど、この後の処理ではstudentの変数はPersonクラスとしてしか扱わない(Personで定義されたメソッドしか呼ばない)」 という"意図"を表現することができます。 (キャストしてれば意味ないですが、そもそもキャストするならば、最初からStudent型で宣言するでしょうし) 一方 Student student = new Student(); というようになっていた場合は、Studentクラス独自のメソッドを使っているかどうかは、その後のコードをおってみないとわかりません。 それ以外の違いとしては、 Student student = new Student(); とした場合は、studentという変数には、Studentクラス(またはそのサブクラス)のインスタンスしか再代入できませんが、 Person student = new Student(); という場合は、Personクラスのインスタンスを再代入できるという点で、異なります。(ローカル変数よりも、インスタンス変数の場合はこういうパターンが多くなると思います) あとは Student student = new Student(); というように、インスタンスを生成して、それをすぐに一時変数に格納する場合は、確かに親クラスの型の変数に代入するというのは少ないと思いますが、 コレクション(ListやMapやSetなど)に格納する場合のジェネリックの型指定や、メソッドの戻り値の型などの場合は、(実際の中身は子クラスでも)親クラスの型を指定する場合が多いです。

kensiroooo
質問者

お礼

長文ありがとうございます。 正直な話、まだまだ分からないことがあり(オーバーロード?) いろいろなことを手探りで考えている途中であります。 ”ん~”と、うなってしまいました。 ポリモーフィズムという概念は意外と?深く、 もう少し勉強してから、改めて考え抜きたいと思いました。 ありがとうございました。

  • hoge_piyo
  • ベストアンサー率57% (15/26)
回答No.3

型の情報の省略とポリモーフィズムの問題と2つ混じっていますね。 >Student student = new Student();も同じような動きとなる? というのは、似たような動きにはなりますが、できることは若干違います。たとえば、Studentだけに定義されたメソッドを呼べません。 >student = new Student();として宣言できても良い と言う点に関しては、冗長ということでしょうが、次期VersionのJava7では、(上記とは少し違いますが)省略した書き方を認めようという動きがあります。 他にも、C#などはvarキーワードがあり勝手に型推論してくれますし、他にも関数型言語では型推論をしてくれるので、省略出来る場合があります。

kensiroooo
質問者

お礼

ありがとうございます。 >若干違います。 とのことですが、詳細教えてもらえますか? public class Parson{ void m() } public class Student extends Parson{ void m()} 上記の場合に、 Parson student = new Student(); と宣言した場合、 m()は、Studentのm()でしょうか? となればの話ですが、親クラスで子クラスのメソッドをすべて 宣言しておけば、ますます型を宣言した代入方法は いらない方向となりませんか? Java7ではそのような動きがあるのは必然!? ん~、分かったような、分からなくなったような。そんな感じです。 理解は深まりました。ありがとうございます。

  • askaaska
  • ベストアンサー率35% (1455/4149)
回答No.2

つまりコーディングの手間を省けたらなってことかしら? そうね A a = new A() のように宣言型とコンストラクタが一致する時に限っては a = new A() こう書いてもOKにしてしまうのもありね。 そうなっていないのはスコープの管理じゃないかしら。 コード内のある1点を見たとき a = new A() こう記述してある場合 これが A a = new A() の省略なのか それともどこかで変数宣言されている可能性もあるわ。 具体的に書くと A a; void load() { a = new A(); } と A a; void load() { A a = new A(); } この2つはまったく別のものだわね。 Javaの場合こういう記述も可能だから スコープを明確にする必要があるんだと思うわよ。

kensiroooo
質問者

お礼

ありがとうございます。 ふむふむ、スコープを明確にすることは、 コーディングをする上でとても大切なことですよね。 なるほど。 とても参考になりました。

関連するQ&A