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

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

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

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

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

3回答

5505閲覧

ポリモーフィズムについて

kazum77

総合スコア12

オブジェクト指向

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

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2016/12/03 12:24

ポリモーフィズムについていま勉強してるのですがポリモーフィズムについての利点と欠点がよく分かりません。
あと勉強してるなかでポリモーフィズムはなんとなく継承と似てるような気がしますのですが違いはあるのでしょう。
解説

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

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

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

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

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

guest

回答3

0

ポリモーフィズムというのは、一つの名前に複数の実体を関係づけ、そして、その名前を使うときに、使っている場所のコンテキストによって実体が自動的に選択される仕組みのことです。こういう一般的な言い方だと、何言っているのか、よくわからないので具体例を示してみます。

変数の中身を、簡単な型の説明付きで表示する関数、printMe を作るとします。

C++

1#include <iostream> 2using namespace std; 3 4void printMe(int v) 5{ 6 cout << "int:" << v << endl; 7} 8 9void printMe(double v) 10{ 11 cout << "double:" << v << endl; 12} 13 14int main() 15{ 16 int i = 1; 17 double d = 2.5; 18 19 printMe(i); // int:1 20 printMe(d); // double:2.5 21 22 return 0; 23}

上の例では、printMe という一つの名前に、引数が int用の関数の実体と、double用の実体の二つが結びついています。printMe という機能を呼び出すとき、引数の型によって、違う関数の実体が呼び出されているのが分かると思います。

printMe というのは、使う側からすれば、変数の中身を簡単な説明付きで表示したい、という一つの目的しかありません。しかし、実際にコーディングすると、変数の型によって、やり方を変えなければなりません。ポリモーフィズムがなければ、intの変数にはprintMeIntを、doubleの変数にはprintMeDoubleを使うといったようなことをしなければならず、変数を表示したいだけなのに、いくつも名前を使い分けなければならず面倒です。ポリモーフィズムがあれば、一つの目的に一つの名前で済み、プログラムが作りやすく、わかりやすくなります。これがポリモーフィズムの利点です。(逆に言えば、違う目的なのに同じ名前を付けてしまうこともできるわけで、そうなると悲惨です。)

継承とポリモーフィズムの関係ですが、上の例で分かるように、ポリモーフィズムには継承が絶対に必要というわけではありません。

C++ や Java のような言語では変数にも型があり、あるクラスの変数には、そのクラスか、そのサブクラスのオブジェクトしか代入できません。したがって、オブジェクト間でポリモーフィズムを利用しようとすると、継承をつかってクラスの親子関係を定義しなければなりません。

一方、例えば Python のように変数には型がない言語では、継承なしでもポリモーフィズムが利用可能です。

投稿2016/12/04 00:46

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

raccy

2016/12/04 01:03

このコードはポリモーフィズムではなくオーバーロードによる動作ではないのでしょうか? ポリモーフィズムは全く関係無いと思うのですが…。
退会済みユーザー

退会済みユーザー

2016/12/04 01:11

ポリモーフィズム自体は、オブジェクト指向言語に限らない概念ですし、オーバーロードというのはポリモーフィズムの一形態であるというのが、私の解釈です。
raccy

2016/12/04 02:47

私はオーバーロードとポリモーフィズムは無関係だと長い間思っていました。hideki1234さんの指摘で色々調べましたが、さらにわからなくなってしまいました。別途、質問を上げましたので、もし、お時間がよろしければ、ご回答いただくと幸いです。 https://teratail.com/questions/57562
yohhoy

2016/12/05 02:02 編集

+1; 私もhideki1234さんの解釈に同意です(ただこの質問に対する回答としては、少々飛躍があるかもしれません)。 raccyさんの質問にも詳細回答しました。
guest

0

こんにちは。

ポリモーフィズムはなんとなく継承と似てるような気がしますのですが

普通、ポリモーフィズムは継承して実現しますよ。

さて、派生クラスのインスタンスを基底クラス型のポインタで指し示することができるのがポリモーフィズムです。
何が嬉しいかというと、基底クラスへのポインタで様々な派生クラスのインスタンスを管理できますし、操作することさえできます。

例えば、基底クラスとしてペットクラスがあって、それを派生して犬クラスや猫クラスを作ったとします。
ペットクラスへのポインタ配列を作り犬クラスのインスタンスへのポインタや猫クラスのインスタンスへのポインタを代入できます。(普通は型が違うと代入できませんが、基底クラスへのポインタであればできます。)
更に、そのポインタ配列の要素をforループで回して、登録されているペットインスタンスに「鳴け」と指示したら、犬クラスのインスタンスは「ワンワン」と返して、猫クラスのインスタンスは「ニャーニャー」と返すことができます。
これは本当に便利ですよ。

投稿2016/12/03 12:55

Chironian

総合スコア23272

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

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

0

C++

1#include <iostream> 2 3class Crier 4{ 5public: 6 virtual void cry() = 0; 7}; 8 9 10class Baby : public Crier 11{ 12public: 13 Baby() { } 14 15 void cry() 16 { 17 std::cout << "おぎゃー\n"; 18 } 19}; 20 21 22class Cat : public Crier 23{ 24public: 25 Cat() { } 26 27 void cry() 28 { 29 std::cout << "ニャーニャー\n"; 30 } 31}; 32 33 34class Horse : public Crier 35{ 36public: 37 Horse() { } 38 39 void cry() 40 { 41 std::cout << "ヒヒーン\n"; 42 } 43}; 44 45 46int main(int argc, char* argv[]) 47{ 48 Crier* criers[] = { new Baby(), new Cat(), new Horse() }; 49 50 for (int i = 0; i < sizeof(criers) / sizeof(criers[0]); i++) 51 { 52 criers[i]->cry(); 53 } 54 55 return 0; 56}

呼び出し側は criers[i]->cry(); だけなのに、それぞれの派生クラスのcry()が呼び出されます。
Catクラスのcry()の実装を、「猫の鳴き声のオーディオファイル再生」に変えても、
呼び出し側を一切変更せずに、「猫の鳴き声のオーディオファイル再生」ができます。
継承とオーバーライドのルールに従えば、未実装の関数さえ呼び出すコードが書けるのです。

投稿2016/12/04 01:44

naomi3

総合スコア1105

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問