質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
オブジェクト指向

オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

Q&A

解決済

4回答

1633閲覧

ポリモーフィズムと、継承やオーバーライドの関係

veee

総合スコア7

オブジェクト指向

オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

1グッド

3クリップ

投稿2018/05/04 10:50

ポリモーフィズムとは、同名のメソッドで、オブジェクトに合わせた異なる振る舞いをさせるという概念だという認識でいます。
まず、この認識は間違っていないでしょうか。
意味を調べていると、その説明と同時に継承やオーバーライドという言葉がよく出てくるのですが、
これらはポリモーフィズムを実現させるために必須なのでしょうか。
ポリモーフィズムの意味が、始めに書いた通りであるだけだとするなら、必須ではないように思うのですがいかがでしょう。

以下は、継承もオーバーライドもしていません。ポリモーフィズムとはいえませんか。

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();
LouiS0616👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

ベストアンサー

ポリモーフィズムとは、同名のメソッドで、オブジェクトに合わせた異なる振る舞いをさせるという概念だという認識でいます。

まず、この認識は間違っていないでしょうか。

「オブジェクトに合わせた実装で、メソッド名に合わせた振る舞いをさせる」と言った方が良いと思います。

意味を調べていると、その説明と同時に継承やオーバーライドという言葉がよく出てくるのですが、これらはポリモーフィズムを実現させるために必須なのでしょうか。

必須ではありません。
Javaなどの静的型付け言語では、コンパイル時の型チェックのために継承やインターフェースを使用して、あらかじめメソッドの出自が同じことを宣言しておく必要がありますが、PHPなどの動的型付け言語では、出自が異なってもメソッドが同じように呼び出せるなら、それは同じように扱えます。

投稿2018/05/04 12:33

編集2018/05/04 12:42
hichon

総合スコア5737

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

maisumakun

2018/05/04 12:51

Javaの場合、インターフェースがあっても実装は(デフォルト実装がない場合)それぞれしないといけないので、「出自が同じ」というよりは「統一的に扱うための枠組みを宣言する」といったほうが正しいのではないかと思います。
guest

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
Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

veee

2018/05/05 06:40

PHPの例は、ダックタイピングな“ポリモーフィズムである”と言えるのですね。 開発時に、広い意味でのポリモーフィズムが好まれないことは把握できます。 理解を進める上で、ポリモーフィズムの意味をまず確かなものにしたいと思った次第です。 ここの回答の中にもあるように、ポリモーフィズムとは継承してオーバーライドすること。 というような説明をされている人が少なからずいて、 一体どこまでがポリモーフィズムなのか把握できずにいます。 私の認識が間違いでないなら、このまま先に進めると思っています。
Chironian

2018/05/05 06:54

> 一体どこまでがポリモーフィズムなのか把握できずにいます。 どこまでがポリモーフィズムなのかは、人によって違います。 例えば、どこまでがおやつなのか(バナナを含む?含まない?)は、人(立場?)によって違うでしょう。 似たようなものですよ。
guest

0

ポリモーフィズムとは、同名のメソッドで、オブジェクトに合わせた異なる振る舞いをさせるという概念だという認識でいます。
まず、この認識は間違っていないでしょうか。

基本的には合っています。

以下は、継承もオーバーライドもしていません。ポリモーフィズムとはいえませんか。

言えません。この例は、クラスAとクラスBのインタフェース(関数名)がたまたま同じなだけです。

ポリモーフィズムとは、クラスAを継承したクラスB1とB2があり、B1とB2のどちらのインスタンスもクラスAのインスタンスであるかの様に扱える事を指します。

例えば、クラスAとして「任意の要素数を格納可能なリスト構造」を、B1とB2をそれぞれ「可変長配列」「線形リスト」と考えると、ポリモーフィズムの意味・効果が理解しやすいと思います。

投稿2018/05/04 10:58

rtr1950x

総合スコア298

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kawakawa2018

2018/05/04 11:17

こんばんは これらはポリモーフィズムを実現させるために必須なのでしょうか。 についてですが補足になれば。 昔からよくある図ですが [7] 継承とポリモーフィズム http://www.isl.ne.jp/pcsp/JavaToYou/java_09.html#mokuji7 「継承」、「オーバーライド」、「キャスト」について説明しました。 これでポリモーフィズムを実現できます。 オーバーロードとは異なる方法...
maisumakun

2018/05/04 12:47

PHPやRuby、JavaScriptのような動的型付け言語では、明示的なインターフェースがなくても(RubyやJavaScriptにはそもそもインターフェースがないし)、まさに「同じ名前のメソッドを実装する」ことで、ダックタイピングにより動的ポリモーフィズムを実現できます。
veee

2018/05/04 17:31

継承が必須であるという意見と、必須でないという意見が出ている様に思います。 私のポリモーフィズムに対する認識が大方間違いでないのなら、 やはり継承は必須でないことになるはずです。 私が示した例は“ダックタイピングによる動的ポリモーフィズム”には該当しないのでしょうか。
guest

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
HogeAnimalLover

総合スコア4830

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問