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

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

ただいまの
回答率

90.50%

  • オブジェクト指向

    284questions

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

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

解決済

回答 4

投稿

  • 評価
  • クリップ 3
  • VIEW 487

veee

score 1

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

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

class A{
    function method(){
        echo "A";
    }
}

class B{
    function method(){
        echo "B";
    }
}

$a = new A();
$b = new B();

$a->method();
$b->method();
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 4

checkベストアンサー

+3

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

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

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

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

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/05/04 21:51

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

    キャンセル

+2

こんにちは。

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

「ポリモーフィズム」という言葉に厳密な定義があるわけではないようですので、人によって解釈が異なります。
私自身は「異なるものを同じように使えること」を最も広い意味での「ポリモーフィズム」と理解しています。PHPの例はこれに該当しますし、veeeさんのその認識を、私は間違ってはいないと思います。

しかし、プログラム開発時のデザイン・パターン的な話題の時にそこまで意味を広げると何を言っているのか判らなくなりますので、正直そこまで広い意味で使うのは個人的にあまり好きではありません。
どちらかというと狭い意味のポリモーフィズム(仮想関数があるクラスを継承し、基底クラスへの参照で統一的に扱えるようにする)で使う方を私は好みます。

C++のような厳密な静的型付け言語の場合、「後者を除く前者(例えばPHPで記述されたコード)」と「後者」の使い方には決定的な差があります。
後者は基底クラス型の参照で派生クラスのインスタンスを参照できます。つまり、その「基底クラス型の参照」がどの派生クラスを参照していても同じように使えます。
「後者を除く前者」は様々な実装が有りますが、私の知る限り静的型付け言語で同じことはできません。

しかし、動的型付け言語ではある変数が保持するインスタンスの型は任意ですから、PHPで書かれたようなコードでも次のようなことができるのではないでしょうか?(すいません。PHPは知らないので構文的に間違っているかも)

$a = new A();
$b = new B();

$ab = $a
$ab->method();  // A

$ab = $b
$ab->method();  // B


ですので、動的型付け言語では「後者を除く前者」と「後者」の間に決定的な差はないと思います。

因みに、この書き方はダック・タイピングと呼ばれるようですね。
RubyとC++の例どちらとも「後者を除く前者」に属します。


ちょっと話はそれますが。
上記WikipediaのC++の例はテンプレートを使っているので、test()のパラメータ t はコンパイル時にDuckかCatが確定します。実行するまでどちらか判らないというものではありません。
test()の中でt.fly();メソッドを呼び出していたとします。
そして、間違ってtest(Cat());と呼び出そうとすると、ありがたいことにコンパイル・エラーになります。
動的型付け言語の場合、実行時にエラーになるでしょう。プログラムの完全なテストは不可能ですから、見逃した場合お客さんのところで発生します。可能な場合には避けたいシナリオです。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/05/05 15:40

    PHPの例は、ダックタイピングな“ポリモーフィズムである”と言えるのですね。

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

    キャンセル

  • 2018/05/05 15:54

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

    キャンセル

0

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

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

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

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

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

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/05/04 20:17

    こんばんは

    これらはポリモーフィズムを実現させるために必須なのでしょうか。

    についてですが補足になれば。

    昔からよくある図ですが
    [7] 継承とポリモーフィズム
    http://www.isl.ne.jp/pcsp/JavaToYou/java_09.html#mokuji7

    「継承」、「オーバーライド」、「キャスト」について説明しました。
    これでポリモーフィズムを実現できます。
    オーバーロードとは異なる方法...

    キャンセル

  • 2018/05/04 21:47

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

    キャンセル

  • 2018/05/05 02:31

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

    キャンセル

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の呼び出し先を変更できるのでポリモーフィズムと呼べると思います。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

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

  • ただいまの回答率 90.50%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • オブジェクト指向

    284questions

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