アプリ版:「スタンプのみでお礼する」機能のリリースについて

Java初心者です。

Javaの書籍で、ポリモーフィズムを説明している箇所において
オブジェクトを生成する際に、以下のような書き方をしているのを見ます。

1.-----
スーパークラス名 オブジェクト名 = new サブクラスのコンストラクタ名();
--------

上記は、
何を実現する為に、左辺と右辺のクラス名とコンストラクタ名を変えているのでしょうか?
(もちろん詳細は実際に書かれたメソッドや変数によると思いますが、一般的な話として。)
また併せて、

2.-----
サブクラス名 オブジェクト名 = new サブクラスのコンストラクタ名();
-------
と書いた時とでは、使用(アクセス)出来るメソッドや変数、
生成されたオブジェクトの中身が、どのように変わってくるのでしょうか?
2.の方法では、何が実現出来ないのでしょうか?

教えて下さい!

A 回答 (5件)

ここで詳しい説明をするのは大変なので、キーワードだけ。



1) OCP(Open Close Principle)
2) 共通-可変性分析
3) 上位の共通化
4) 抽象化
5) 処理の違い=具象オブジェクトの違い

いずれもオブジェクト指向分析でアプリケーションの構造を決定するときに
用いられるものです。いずれもポリモーフィズムが関連します。

このあたりを調べると、ポリモーフィズムがオブジェクト指向を支えている
ものであることが判ると思います。
    • good
    • 0
この回答へのお礼

ありがとうございます!

学ぶべきキーワードを教えて下さると、次のステップにつながるので助かります!

Java、深いですね、、、おもしろいです。

お礼日時:2011/04/29 10:47

>これは、


>-----
>ArrayList list= new ArrayList();
>-----
>と書いても同じだと感じるのですが、違うのでしょうか?
>この辺りがちょっと分かっておりません。
>
>こう書けばいいものをナゼわざわざ
>List list= new ArrayList();
>って書くのかな~と、、、
>初心者なんで細かいところで足踏みしてしまうのです。。。

まず、開発というものは非常多くの事を考慮して行います。
その考慮を推し量れないとこのような疑問が出てくるのだと思います。
その理由はこの一行だけでは誰もわからないでしょう。

>List list= new ArrayList();

この一行だけで意味を見つけるのだとしたら、
listというオブジェクトに制約を設けるためです。
インターフェースは定義だと前のレスで書きましたが、
このインスタンスはListというインターフェースの定義で使用する
事を強要するという事です。
この場合はArrayListのインスタンスであるにも関わらず、
Listに無いメソッドやグローバル変数にはアクセスができなくなります。

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

これ以上の説明は設計という作業に関係してきます。
まさに題名の「ポリモーフィズム」とはそういう類のものです。
「インターフェース」「設計」などで検索をされてはいかがでしょうか?

あなたが探している答えは実際にこの書き方をされている
コードの中にあると思います。
    • good
    • 0
この回答へのお礼

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

なるほど!そういった類いのものなんですね、ありがとうございます。

お礼日時:2011/04/29 12:08

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はインターフェースなので処理は実際に書かれていないのでが・・・)

何が実現できないとかというよりも目的が違います。

本当はこの技術については非常に高度な設計が絡んできますのでこの場所で説明は無理です。

この回答への補足

皆さんご丁寧に回答して下さって、本当にありがとうございます!

covachan様から頂いた回答に更に質問ですが、

>例えば、
>
>List list= new ArrayList();
>
>とした時を考えてください。
>list.add("a");
>とした時に呼び出されるaddの処理はListではなくArrayListのaddの処理が
>呼び出されます。

これは、
-----
ArrayList list= new ArrayList();
-----
と書いても同じだと感じるのですが、違うのでしょうか?
この辺りがちょっと分かっておりません。

こう書けばいいものをナゼわざわざ
List list= new ArrayList();
って書くのかな~と、、、
初心者なんで細かいところで足踏みしてしまうのです。。。

補足日時:2011/04/25 23:10
    • good
    • 0

一般的にプログラミングを行う上では、


2.の書き方をしても、1.の書き方をすることは滅多にありません。
使用するスコープ内で、わざわざスーパークラスにダウンキャストしても、
使用できるメソッドが制限されるデメリットのみで、得られるメリットはありません。
書籍上で、機能の説明をするために記述してあると考えられます。

2.の記述では出来て、1.の記述でしかできないことはありませんが、その逆はあります。
実際に生成されたオブジェクト (インスタンス)の内容が変わるといったことはありません。

では、どういう時に例題のようなポリモーフィズムを利用するかというと、
メソッドや、コンストラクタの引数に利用する際です。
これは、java.io.Writer / java.io.Reader などがよく例に挙げられます。
メソッドに引数には、スーパークラスで定義し、実装ではサブクラスを与えるといった使い方です。

他にも、もう少し高度になると Factory を使用した際にも有効になります。
これは、Springframework や S2 といったフレームワークを使うようになると、
その利便性が体感できると思います。
    • good
    • 0

例えば



「学校の関係者」
というスーパークラスがあります
サブクラスとして
「教師」「生徒」「PTA」なんかがあります。

「学校の関係者」 田中先生 = new 「教師」();
「学校の関係者」 山田さん = new 「生徒」();
のような感じですか。
これは、処理の中で「学校の関係者」であることを求められているときに利用します。
つまり、田中先生や山田さんが教師だろうが生徒だろうが関係ないような場合ですね。
例えば「学校の関係者」共通の権限の判定に使ったりします。
他にも「学校の関係者」には共通のメソッドがあり
その結果だけが重要でその処理内容はどうでもいい場合にも利用します。

「教師」 田中先生 = new 「教師」();
「生徒」 山田さん = new 「生徒」();
こうする場合は、処理の中で教師であること、生徒であることを明確に区別する必要があるときに利用します。
例えば「教師」特有「生徒」特有の権限の判定に使ったりします。
他にも「教師」や「生徒」専用のメソッドを使うためにはこうしないと利用できません(キャストすれば別ですが)。


まあ、一番多いのはメソッドの利用ですね。
メソッド=権限ですし。
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!