Java初心者のためのポリモーフィズムについての質問

このQ&Aのポイント
  • Javaのポリモーフィズムにおいて、オブジェクトを生成する際にクラス名とコンストラクタ名を変える理由や効果について教えてください。
  • また、クラス名とコンストラクタ名を変えた場合と変えない場合で使用できるメソッドや変数、生成されたオブジェクトの中身がどのように変わるかも教えてください。
  • Java初心者が理解するためのポイントについても教えていただきたいです。
回答を見る
  • ベストアンサー

インスタンス化について(ポリモーフィズムについて)

Java初心者です。 Javaの書籍で、ポリモーフィズムを説明している箇所において オブジェクトを生成する際に、以下のような書き方をしているのを見ます。 1.----- スーパークラス名 オブジェクト名 = new サブクラスのコンストラクタ名(); -------- 上記は、 何を実現する為に、左辺と右辺のクラス名とコンストラクタ名を変えているのでしょうか? (もちろん詳細は実際に書かれたメソッドや変数によると思いますが、一般的な話として。) また併せて、 2.----- サブクラス名 オブジェクト名 = new サブクラスのコンストラクタ名(); ------- と書いた時とでは、使用(アクセス)出来るメソッドや変数、 生成されたオブジェクトの中身が、どのように変わってくるのでしょうか? 2.の方法では、何が実現出来ないのでしょうか? 教えて下さい!

  • Java
  • 回答数5
  • ありがとう数2

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

  • ベストアンサー
  • covachan
  • ベストアンサー率38% (46/120)
回答No.4

>これは、 >----- >ArrayList list= new ArrayList(); >----- >と書いても同じだと感じるのですが、違うのでしょうか? >この辺りがちょっと分かっておりません。 > >こう書けばいいものをナゼわざわざ >List list= new ArrayList(); >って書くのかな~と、、、 >初心者なんで細かいところで足踏みしてしまうのです。。。 まず、開発というものは非常多くの事を考慮して行います。 その考慮を推し量れないとこのような疑問が出てくるのだと思います。 その理由はこの一行だけでは誰もわからないでしょう。 >List list= new ArrayList(); この一行だけで意味を見つけるのだとしたら、 listというオブジェクトに制約を設けるためです。 インターフェースは定義だと前のレスで書きましたが、 このインスタンスはListというインターフェースの定義で使用する 事を強要するという事です。 この場合はArrayListのインスタンスであるにも関わらず、 Listに無いメソッドやグローバル変数にはアクセスができなくなります。 コードというものは様々なコードとの整合性を考える必要があります。 そういいた意味で、この一行だけでなくプログラム全体を見通した時、 >List list= new ArrayList(); という一行に意味を持つ事もあります。 これ以上の説明は設計という作業に関係してきます。 まさに題名の「ポリモーフィズム」とはそういう類のものです。 「インターフェース」「設計」などで検索をされてはいかがでしょうか? あなたが探している答えは実際にこの書き方をされている コードの中にあると思います。

hakase-chan
質問者

お礼

>コードというものは様々なコードとの整合性を考える必要があります。 >そういいた意味で、この一行だけでなくプログラム全体を見通した時、 >>List list= new ArrayList(); >という一行に意味を持つ事もあります。 なるほど!そういった類いのものなんですね、ありがとうございます。

その他の回答 (4)

回答No.5

ここで詳しい説明をするのは大変なので、キーワードだけ。 1) OCP(Open Close Principle) 2) 共通-可変性分析 3) 上位の共通化 4) 抽象化 5) 処理の違い=具象オブジェクトの違い いずれもオブジェクト指向分析でアプリケーションの構造を決定するときに 用いられるものです。いずれもポリモーフィズムが関連します。 このあたりを調べると、ポリモーフィズムがオブジェクト指向を支えている ものであることが判ると思います。

hakase-chan
質問者

お礼

ありがとうございます! 学ぶべきキーワードを教えて下さると、次のステップにつながるので助かります! Java、深いですね、、、おもしろいです。

  • covachan
  • ベストアンサー率38% (46/120)
回答No.3

No.2さんの回答がしっくり来ますね。 >これは、java.io.Writer / java.io.Reader などがよく例に挙げられます。 >メソッドに引数には、スーパークラスで定義し、実装ではサブクラスを与えるといった使い方です。 ただ、この部分ですが、 この記述はインターフェースこ事だと思われます。 サブクラスは機能拡張、インターフェースは定義ですから。 あくまで私の使用例ですが、 1.の場合はポリモーフィズムにて、インスタンスを持たせたオブジェクトメソッドの 処理内容を切り替えたいときに使用します。 例えば、ある条件ではスーパークラス(インターフェース)ではなく サブクラス(実装クラス)のオーバーライド(実装)された同名のメソッドを使用するということです。 これはインターフェースとしての使い方です。 サブクラスは既存クラスに対し、何らかの追加機能をする時や既存機能を 改ざんしたい時にのみ使用します。 例えば、ArrayListを使用しているプログラムにデバッグ用に中のデータを表示したいとします。 そのためにdebug()というメソッドを追加してSystem.outへ内容を出力させる処理を追加。 というような使い方ですね。 この場合、ArrayListを継承しているため、コードの変更は不必要になります。 ArrayList list = new DebugableArrayList(); list.add("a"); ((DebugableArrayList)list).debug(); のような使い方ですね。 2.についてはそもそも普通の使い方がありますので特に意識はしません。 >と書いた時とでは、使用(アクセス)出来るメソッドや変数、 >生成されたオブジェクトの中身が、どのように変わってくるのでしょうか? >2.の方法では、何が実現出来ないのでしょうか? 例えば、 List list= new ArrayList(); とした時を考えてください。 list.add("a"); とした時に呼び出されるaddの処理はListではなくArrayListのaddの処理が呼び出されます。 ちなみにもし、Lsitのaddを呼び出したい場合は実装クラスのaddメソッド内で super.add()という処理を書けばアクセスできます。 (Listはインターフェースなので処理は実際に書かれていないのでが・・・) 何が実現できないとかというよりも目的が違います。 本当はこの技術については非常に高度な設計が絡んできますのでこの場所で説明は無理です。

hakase-chan
質問者

補足

皆さんご丁寧に回答して下さって、本当にありがとうございます! covachan様から頂いた回答に更に質問ですが、 >例えば、 > >List list= new ArrayList(); > >とした時を考えてください。 >list.add("a"); >とした時に呼び出されるaddの処理はListではなくArrayListのaddの処理が >呼び出されます。 これは、 ----- ArrayList list= new ArrayList(); ----- と書いても同じだと感じるのですが、違うのでしょうか? この辺りがちょっと分かっておりません。 こう書けばいいものをナゼわざわざ List list= new ArrayList(); って書くのかな~と、、、 初心者なんで細かいところで足踏みしてしまうのです。。。

noname#155524
noname#155524
回答No.2

一般的にプログラミングを行う上では、 2.の書き方をしても、1.の書き方をすることは滅多にありません。 使用するスコープ内で、わざわざスーパークラスにダウンキャストしても、 使用できるメソッドが制限されるデメリットのみで、得られるメリットはありません。 書籍上で、機能の説明をするために記述してあると考えられます。 2.の記述では出来て、1.の記述でしかできないことはありませんが、その逆はあります。 実際に生成されたオブジェクト (インスタンス)の内容が変わるといったことはありません。 では、どういう時に例題のようなポリモーフィズムを利用するかというと、 メソッドや、コンストラクタの引数に利用する際です。 これは、java.io.Writer / java.io.Reader などがよく例に挙げられます。 メソッドに引数には、スーパークラスで定義し、実装ではサブクラスを与えるといった使い方です。 他にも、もう少し高度になると Factory を使用した際にも有効になります。 これは、Springframework や S2 といったフレームワークを使うようになると、 その利便性が体感できると思います。

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

例えば 「学校の関係者」 というスーパークラスがあります サブクラスとして 「教師」「生徒」「PTA」なんかがあります。 「学校の関係者」 田中先生 = new 「教師」(); 「学校の関係者」 山田さん = new 「生徒」(); のような感じですか。 これは、処理の中で「学校の関係者」であることを求められているときに利用します。 つまり、田中先生や山田さんが教師だろうが生徒だろうが関係ないような場合ですね。 例えば「学校の関係者」共通の権限の判定に使ったりします。 他にも「学校の関係者」には共通のメソッドがあり その結果だけが重要でその処理内容はどうでもいい場合にも利用します。 「教師」 田中先生 = new 「教師」(); 「生徒」 山田さん = new 「生徒」(); こうする場合は、処理の中で教師であること、生徒であることを明確に区別する必要があるときに利用します。 例えば「教師」特有「生徒」特有の権限の判定に使ったりします。 他にも「教師」や「生徒」専用のメソッドを使うためにはこうしないと利用できません(キャストすれば別ですが)。 まあ、一番多いのはメソッドの利用ですね。 メソッド=権限ですし。

関連するQ&A

  • ポリモーフィズムについて考えている途中、思ったことがありまして

    ポリモーフィズムについて考えている途中、思ったことがありまして 解決できそうもなかったので、質問させてください。 ----------------------------------------------------- オブジェクトStudentには、親クラスPersonがいる。 Person student = new Student(); ----------------------------------------------------- 上記のようにポリモーフィズムの考え方として、 「インスタンスは親クラスの型を持つ変数に代入できる」のですが、 Student student = new Student(); も同じような動きとなる?のであれば、 student = new Student(); として宣言できても良いように思います。 なぜ、そうなっていないのか理由がありますか? また、説明が”とんちんかん”なことになっていますか? なにか、ヒントがあればよろしくお願いします。

    • ベストアンサー
    • Java
  • Javaのインスタンス化の構文のイメージができない

    こんばんは。 Javaプログラマを勉強しています。 サンプルプログラムで、オブジェクトの作成時、左辺と右辺でクラス名が異なる場合、 その一文ではどういうことが行われているのかイメージができません。 そこから原点に戻って、オブジェクトを作成する時の構文の一語一語の意味が分からなくなっています。 テキストによくある簡単な例だと、 ----------------- A a = new A(); ----------------- という構文があります。 この場合は左辺のAと右辺のAが同じであるため、このような構文が普通だと思い、ずっと理解した気になっていました。 ところが、 ----------------- class A {  … } class B extends A{  … } public class Main(){ public static void main(String[] args){  A a = new B();  … } ----------------- という構文が出てきた時、 A a = new B();  で、左辺のAと右辺のBは違っても大丈夫なの?何故違うの?どういう場合にこのような構文を使うの? などの疑問が出てきて、 そもそもインスタンス化の構文 A a = new A(); のそれぞれは何を意味しているのか判らなくなり、 どこからどうやって理解していけば良いのか途方にくれています。 aはインスタンス化したオブジェクトの変数名であることは理解しています。 左辺のAと、右辺のAとnew演算子をどう理解すれば良いのか悩んでいます。 自分も何が分からないかを上手く説明できないのですが、 よろしくお願いします。

  • クラスのインスタンスの生成

    javaの勉強を始めたばかりの初心者です。 クラスのオブジェクトの生成方法は(1)の方法だけだと思っていたのですが, 本を読んでいると以下の(1)~(3)の3種類の生成の方法がでてきます。 オブジェクトの生成方法について以下の質問にお答えいただきたいです。 【質問1】 (2)のオブジェクトの生成方法は以下のような考え方でしょうか? BufferedReader br = new BufferedReader(); InputStreamRader k = InputStream(); BufferedRader br = new BufferdRader(k); これを省略して・・・ BufferedReader br = new BufferedReader(new InputStreamReader ()); 【質問2】 (3)のオブジェクト生成方法は以下の考え方でしょうか Container ct = new Container(); ct = frame.getContentPane(); これを省略して・・・・ Container ct = frame.getContentPane(); 【質問3】 オブジェクト生成方法はこの3種類の他にもあるのでしょうか 【質問4】 (1)~(3)の方法には使い分け(ルール)があるのでしょうか? 例えば「このクラスの場合この方法」というような -------------------------------------------------------------------- (1)MyClass br = new MyClass();   クラス名 オブジェクト = new コンストラクタ; -------------------------------------------------------------------- (2)BufferedReader br = new BufferedReader(new InputStreamReader ()); -------------------------------------------------------------------- (3)Container ct = frame.getContentPane(); --------------------------------------------------------------------

    • ベストアンサー
    • Java
  • ガーベージコレクション?

    Javaにガーベージコレクションってあるじゃん。重要そうなのですが、私の理解はイマイチです。ガーベージコレクションって何ですか?一言で言えば、ごみインスタンスなのかな。 以下は私独学の推測 インスタンスを作るとき、new Constructor();ってやるじゃん。だけど、これだけだとガーベージコレクションになって、そのうち自動的にインスタンスが消えるのかな? インスタンスを残そうとすると、左辺が重要である。 ◯ City tokyo=new City();(左辺=右辺;の形) × new City();(右辺;の形で、左辺=を省略している) 恒久的インスタンスにしようとすると、左辺で変数のクラス型と変数名を指定して、右辺の受け皿(代入先)を用意する。City型のインスタンスを作るだけなら、左辺を省略してnew City();だけで十分。しかし、これだとガーベージコレクションになって、すぐ消える。 正しい?

    • ベストアンサー
    • Java
  • メソッドの引数としてのthisの意味

    java初心者です。教えてください。 メソッドの引数としてのthisは何を表しているのですか? いろいろ調べてみてthisには以下の2つの使用法があることがわかりました。 1.インスタンス変数の名前とインスタンスメソッド内のローカル変数名がかぶったときに、メソッド内でインスタンス変数を表すときにthis.変数名とする。 2.あるクラスのコンストラクタ内で、同じクラスの別のコンストラクタを呼ぶときに使う。 しかし、引数としてのthisの意味がわかりません。 具体的には、addMouseListener(this);や、g.drawImage(img,10,10,this);のthisです。 後者の場合はオブジェクトgのインスタンスメソッドなので、thisはオブジェクトgへの参照を表しているのでしょうか?

    • ベストアンサー
    • Java
  • javaで、オブジェクトを生成しないとメソッドは使えないんですか?

    javaで、オブジェクトを生成しないとメソッドは使えないんですか? そのように習ったのですが、サブクラスのメソッド定義の中で、オブジェクトを生成せずにスーパークラスのメソッドを使える例(下に簡単に書きました)をみて、分からなくなってしまいました。 おしえてください、よろしくおねがいします。 ------------------------------- class superclass { method_a(){ ~~~~ } } --------------------------- class subclass { method_b(){ super.method_a(); }

    • ベストアンサー
    • Java
  • Ruby 特異メソッドのnewが先に実行?

    Rubyのインスタンス生成について質問があります。 通常クラスを定義する場合は class Hoge ; def hello(); pirnt "hello"; end であると思います。 ただ Hoge = Class.new(); でもクラスは定義できるとききました。 ただこの場合Hogeクラスに定義できるのは HogeというClassクラスから作られた特異クラスとしてのHogeに 特異メソッドのみを定義できるということですよね? 通常のインスタンスメソッドは定義できませんよね? ではでは、 hoge = Class.new(); とした場合はどうなるのでしょうか? この場合は Classクラスの純粋なインスタンスとなるのでしょうか? 前者の定義とおなじ仕方ですが代入先が、通常の変数です。 この場合は、クラスオブジェクトとして生成されるのですか? オンラインマニュアルをみたところ 「新しく名前の付いていない superclass のサブクラスを生成します。 superclass が省略された時にはObject のサブクラスを生成します。 名前のないクラスは、最初に名前を求める際に代入されている定数名を検索し、見つかった定数名をクラス名とします。」 とあります。 上記内容は Classクラスの特異クラスとして定義されている特異メソッド(new)です。 これは Class.new()で作られたインスタンスを代入する先が定数であればその定数名と同じクラスを定義しつつそのClassクラスのクラスオブジェクトを生成するという意味合いでまちがいないでしょうか? 上記のとおりであれば hoge =Class.new()の場合は、やはりhogeというクラスを定義することになるのでしょうか? クラス定義は定数でなければならないはずですよね。 ただ実際、 p hoge;として出力すると#とひょうじされています。これはhogeがクラスオブジェクトではなく ただのインスタンスであるということでしょうか? であるならばこの hoge = Class.new()の式のnewはClassクラスオブジェクトに定義された特異メソッドではなく Classクラスに定義されたnewメソッド・・・・・つまりClassクラスに定義されたインスタンスメソッドの方のnewメソッドだとおもうのですが・・・・・・。 つまりこちらのメソッドですね。 「new( ... ) クラスのインスタンスを生成して返します。このメソッドの引数はブロック引数も含め initialize に渡されます。」 ※オンラインリファレンスから参照しました。 しかし 通常メソッドの検索は特異メソッドからはじまりその後クラスのインスタンスメソッド->親クラスのメソッドと 検索して行くとあります。 必ず先に、特異メソッドを実行しているはずだと思うのですが・・・。 やはり特異メソッドnewを実行しているのでしょうか? 長々すみませんが、ご教授ください。

    • ベストアンサー
    • Ruby
  •  superについて教えて下さい

     superについて教えて下さい  JAVAの初心者です、宜しくお願いします。  「super」についてよくわかりません。 ある本には、「親クラスのコンストラクタを呼び出す」、またある本には、「親クラスのオブジェクトを呼 び出す」、と書かれていました。  ・コンストラクタとオブジェクトとは同じ意味なのでしょうか。  ・また、ある本には、「コンストラクタの継承はされない」とかかれていますが、どのように違うのでしょうか。  ・JAVAのApIには、次のように書かれています。   「paint     public void paint(Graphics g)コンテナをペイントします。このコンテナの子コンポーネントで    あるすべての軽量コンポーネントへペイント要求を転送します。このメソッドが再実装される場合、軽量    コンポーネントが正しく描画されるように super.paint(g) を呼び出さなければなりません。    (以下略)」   super.paint(g)と各意味は、親クラスのメソッドを呼びだすことで、親クラスのメソッドを呼びだす時に  も、superが必要ということでしょうか。  コンストラクタ自体についてよく理解出来ていないのですが  ・そもそもクラス(オブジェクトの生成)にとってどのような役割、意味があるのでしょうか。   オブジェクトの生成すると、デフォルトで自動的に引数なしのコンストラクタが作成されると書かれています  が、  ・作成されること自体にどのような意味があるのでしょうか。  変数の初期化とかをコンストラクタ内で設定するのは意味があるとは思うのですが、、、、

    • ベストアンサー
    • Java
  • ご教示ください。

    ご教示ください。 javaで日付操作をやっています。 通常、クラスのインスタンスを作成する場合 クラス名 変数名 = new クラス名(); ですが、カレンダークラスを使用した際に Calender 変数名 = Calender.getInstance(); と出てきました。 Calenderクラスにある、getInstanceメソッドを呼び出していると思います。 クラスをインスタンスすることで、そのクラス内にある、メソッドやフィールドを初期値で使えて(コンストラクタがない場合)と認識しています。 インスタンスで、直接、メソッドを呼び出せる場合があるのでしょうか?

  • newしないインスタンス?実体化しなくてもいいの?

    JAVAについて教えて下さい。 ServletContext application = getServletContext(); の成り立ちの意味なのですが、newがなぜないのか教えて下さい。 ~自身の考え~ (1)サーブレットコンテキストというクラスをインスタンス化して (サーブレットコンテキスト 変数A = new サーブレットコンテキスト();)     ↑                         ↑   クラス                       クラス (2)変数Aドットメソッド()によって、代入変数Bを作り上げる (サーブレットコンテキスト 代入変数B = 変数A . メソッド();) (3)のはずが、上記の式にはnewがありません。 なんで?? ~~ ~疑問点~ もしかしたらHttpServletでimportしているからそこでnewインスタンス化宣言している? だとするならどのような式になっているのでしょうか。 もしくはメソッドのF3キーとして上位をたどったときに出てきた public abstract class GenericServlet implements Servlet, ServletConfig, Serializable { public ServletContext getServletContext() { return getServletConfig().getServletContext(); } } として抽象クラスが出てきましたが、どこにもnew実体化していません。 よろしくお願いいたします。

    • ベストアンサー
    • Java

専門家に質問してみよう