ポリモーフィズムとは、同名のメソッドで、オブジェクトに合わせた異なる振る舞いをさせるという概念だという認識でいます。
まず、この認識は間違っていないでしょうか。
意味を調べていると、その説明と同時に継承やオーバーライドという言葉がよく出てくるのですが、
これらはポリモーフィズムを実現させるために必須なのでしょうか。
ポリモーフィズムの意味が、始めに書いた通りであるだけだとするなら、必須ではないように思うのですがいかがでしょう。
以下は、継承もオーバーライドもしていません。ポリモーフィズムとはいえませんか。
php
1class A{ 2 function method(){ 3 echo "A"; 4 } 5} 6 7class B{ 8 function method(){ 9 echo "B"; 10 } 11} 12 13$a = new A(); 14$b = new B(); 15 16$a->method(); 17$b->method();
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

回答4件
0
ベストアンサー
ポリモーフィズムとは、同名のメソッドで、オブジェクトに合わせた異なる振る舞いをさせるという概念だという認識でいます。
まず、この認識は間違っていないでしょうか。
「オブジェクトに合わせた実装で、メソッド名に合わせた振る舞いをさせる」と言った方が良いと思います。
意味を調べていると、その説明と同時に継承やオーバーライドという言葉がよく出てくるのですが、これらはポリモーフィズムを実現させるために必須なのでしょうか。
必須ではありません。
Javaなどの静的型付け言語では、コンパイル時の型チェックのために継承やインターフェースを使用して、あらかじめメソッドの出自が同じことを宣言しておく必要がありますが、PHPなどの動的型付け言語では、出自が異なってもメソッドが同じように呼び出せるなら、それは同じように扱えます。
投稿2018/05/04 12:33
編集2018/05/04 12:42総合スコア5739
0
こんにちは。
ポリモーフィズムとは、同名のメソッドで、オブジェクトに合わせた異なる振る舞いをさせるという概念だという認識でいます。
まず、この認識は間違っていないでしょうか。
「ポリモーフィズム」という言葉に厳密な定義があるわけではないようですので、人によって解釈が異なります。
私自身は「異なるものを同じように使えること」を最も広い意味での「ポリモーフィズム」と理解しています。PHPの例はこれに該当しますし、veeeさんのその認識を、私は間違ってはいないと思います。
しかし、プログラム開発時のデザイン・パターン的な話題の時にそこまで意味を広げると何を言っているのか判らなくなりますので、正直そこまで広い意味で使うのは個人的にあまり好きではありません。
どちらかというと狭い意味のポリモーフィズム(仮想関数があるクラスを継承し、基底クラスへの参照で統一的に扱えるようにする)で使う方を私は好みます。
C++のような厳密な静的型付け言語の場合、「後者を除く前者(例えばPHPで記述されたコード)」と「後者」の使い方には決定的な差があります。
後者は基底クラス型の参照で派生クラスのインスタンスを参照できます。つまり、その「基底クラス型の参照」がどの派生クラスを参照していても同じように使えます。
「後者を除く前者」は様々な実装が有りますが、私の知る限り静的型付け言語で同じことはできません。
しかし、動的型付け言語ではある変数が保持するインスタンスの型は任意ですから、PHPで書かれたようなコードでも次のようなことができるのではないでしょうか?(すいません。PHPは知らないので構文的に間違っているかも)
PHP
1$a = new A(); 2$b = new B(); 3 4$ab = $a 5$ab->method(); // A 6 7$ab = $b 8$ab->method(); // B
ですので、動的型付け言語では「後者を除く前者」と「後者」の間に決定的な差はないと思います。
因みに、この書き方はダック・タイピングと呼ばれるようですね。
RubyとC++の例どちらとも「後者を除く前者」に属します。
ちょっと話はそれますが。
上記WikipediaのC++の例はテンプレートを使っているので、test()のパラメータ t はコンパイル時にDuckかCatが確定します。実行するまでどちらか判らないというものではありません。
test()の中でt.fly();
メソッドを呼び出していたとします。
そして、間違ってtest(Cat());
と呼び出そうとすると、ありがたいことにコンパイル・エラーになります。
動的型付け言語の場合、実行時にエラーになるでしょう。プログラムの完全なテストは不可能ですから、見逃した場合お客さんのところで発生します。可能な場合には避けたいシナリオです。
投稿2018/05/05 03:54
編集2018/05/05 04:02総合スコア23274
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

0
ポリモーフィズムとは、同名のメソッドで、オブジェクトに合わせた異なる振る舞いをさせるという概念だという認識でいます。
まず、この認識は間違っていないでしょうか。
基本的には合っています。
以下は、継承もオーバーライドもしていません。ポリモーフィズムとはいえませんか。
言えません。この例は、クラスAとクラスBのインタフェース(関数名)がたまたま同じなだけです。
ポリモーフィズムとは、クラスAを継承したクラスB1とB2があり、B1とB2のどちらのインスタンスもクラスAのインスタンスであるかの様に扱える事を指します。
例えば、クラスAとして「任意の要素数を格納可能なリスト構造」を、B1とB2をそれぞれ「可変長配列」「線形リスト」と考えると、ポリモーフィズムの意味・効果が理解しやすいと思います。
投稿2018/05/04 10:58
総合スコア298
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/05/04 11:17
2018/05/04 12:47

0
単に字面の通り、「同名のメソッドで別の機能のもの」と捉えただけではポリモーフィズムとはいえません。極端な話、名前空間が異なれば同名の関数を定義することも簡単です。これはオブジェクト指向言語でなくとも当然のことです。
修正
ポリモーフィズムとは継承(実装)によって作成した派生(実装)クラスにおいてメソッドのオーバーライド(同名、同引数のメソッドを上書き定義すること)で実現します。
以下、追記
他の回答を見て、私も調べなおしました。必ずしも継承(実装)が必要というわけではないという資料がありました。例えばオーバーロードとかテンプレート(ジェネリクス)によるものであってもポリモーフィズムと呼ぶそうでした。こうなるとDLLの差し替えとかも一種のポリモーフィズムと呼べると解釈できるのかもしれません。
ただし、課題の中で提示されたプログラムはポリモーフィズムとは呼べないという考えは変わりありません。
$a = new A();
$b = new B();
$a->method();
$b->method();
↑の部分を分離し、↓のように別ファイルにすることができればポリモーフィズムと呼べると思います。
PHPファイル1の一部
$x = new A();
PHPファイル2の一部
$x->method();
これならばPHPファイル1に修正をするだけでPHPファイル2の呼び出し先を変更できるのでポリモーフィズムと呼べると思います。
投稿2018/05/04 11:25
編集2018/05/04 18:17総合スコア4853
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/05/04 12:51