ポリモーフィズムとは何ですか、それは何のためにあり、どのように使用されますか?
ポリモーフィズムとは何ですか、それは何のためにあり、どのように使用されますか?
回答:
この用語のギリシャ語のルーツについて考えると、それが明らかになるはずです。
したがって、ポリモーフィズムとは、異なるプログラミング形式(データ型)に対して同じインターフェースを提示する(プログラミングにおける)機能です。
たとえば、多くの言語では、型が異なるという事実に関係なく、加算、減算、乗算などを行うことができるため、整数と浮動小数点は暗黙的にポリモーフィックです。通常の用語では、オブジェクトと見なされることはほとんどありません。
ただし、同じ方法で、BigDecimal
or Rational
またはorのようなクラスImaginary
は、異なるデータ型を操作する場合でも、これらの操作を提供できます。
古典的な例は、Shape
クラスとそれから継承できるすべてのクラス(正方形、円、12面体、不規則な多角形、スプラットなど)です。
ポリモーフィズムでは、これらのクラスのそれぞれに異なる基礎データがあります。ポイント形状は2つの座標のみを必要とします(もちろん、2次元空間にあると仮定します)。円には中心と半径が必要です。正方形または長方形には、左上隅と右下隅の2つの座標と、(場合によっては)回転が必要です。不規則なポリゴンには一連の線が必要です。
クラスにそのコードとデータを処理させることにより、ポリモーフィズムを実現できます。この例では、すべてのクラスに独自のDraw()
関数があり、クライアントコードは次のように簡単に実行できます。
shape.Draw()
任意の形状の正しい動作を取得します。
これは、コードは、データとは別にされた物事の古い方法とは対照的であり、そして次のような機能を持っているだろうdrawSquare()
とdrawCircle()
。
オブジェクト指向、ポリモーフィズム、継承はすべて密接に関連した概念であり、それらを知ることは不可欠です。私の長いキャリアの間に多くの「銀の弾丸」がありましたが、基本的にはそれが消えてしまいましたが、OOパラダイムは良いものであることが判明しました。学ぶ、理解する、愛する-あなたがやったことを嬉しく思うでしょう:-)
(a)私はもともとそれを冗談として書いたが、それは正しいことが判明したため、それほどおかしくない。モノマーのスチレンはたまたま炭素と水素から作られ、ポリスチレンはそのグループから作られます。C8H8
(C8H8)n
多分私はポリープが手紙の多くの出現であったと述べるべきだっp
たのに、私は冗談を説明しなければならなかったが、それもおかしく見えない。
時々、あなたは後ろにいる間、ただやめるべきです:-)
Poly = many and Morph = change or form
ポリモーフィズムとは、オブジェクトを何かのジェネリックバージョンとして扱うことができる場合ですが、オブジェクトにアクセスすると、コードはオブジェクトの正確なタイプを判別し、関連するコードを呼び出します。
これはC#の例です。コンソールアプリケーション内に4つのクラスを作成します。
public abstract class Vehicle
{
public abstract int Wheels;
}
public class Bicycle : Vehicle
{
public override int Wheels()
{
return 2;
}
}
public class Car : Vehicle
{
public override int Wheels()
{
return 4;
}
}
public class Truck : Vehicle
{
public override int Wheels()
{
return 18;
}
}
次に、コンソールアプリケーションのモジュールのMain()に以下を作成します。
public void Main()
{
List<Vehicle> vehicles = new List<Vehicle>();
vehicles.Add(new Bicycle());
vehicles.Add(new Car());
vehicles.Add(new Truck());
foreach (Vehicle v in vehicles)
{
Console.WriteLine(
string.Format("A {0} has {1} wheels.",
v.GetType().Name, v.Wheels));
}
}
この例では、ベースクラスVehicleのリストを作成します。これは、各サブクラスが持つホイールの数はわかりませんが、各サブクラスが持つホイールの数を知る責任があることは知っています。
次に、自転車、車、トラックをリストに追加します。
次に、リスト内の各Vehicleをループして、それらをすべて同じように扱うことができますが、各Vehicleの「Wheels」プロパティにアクセスすると、Vehicleクラスがそのコードの実行を関連するサブクラスに委譲します。
実行される正確なコードは実行時に参照されるサブクラスによって決定されるため、このコードはポリモーフィックであると言われています。
これがお役に立てば幸いです。
Class_Excel
、Class_CSV
呼ばれるように、または持っているReader
というクラスを。いずれにせよ、if / then / elseをどこかに保存する必要がある場合、ある種の反復処理が必要になります。
PHPでのポリモーフィズムの理解と適用から、Steve Guidettiに感謝します。
ポリモーフィズムは、非常に単純な概念の長い言葉です。
ポリモーフィズムは、共通のインターフェイスを共有しながらクラスが異なる機能を持つオブジェクト指向プログラミングのパターンを表します。
ポリモーフィズムの優れた点は、さまざまなクラスを使用するコードは、どのクラスも同じように使用されるため、どのクラスを使用しているかを知る必要がないことです。ポリモーフィズムの実例はボタンです。ボタンの使い方は誰もが知っています。ボタンを押すだけです。ただし、ボタンの「機能」は、ボタンが何に接続されているか、およびボタンが使用されるコンテキストによって異なりますが、結果はボタンの使用方法には影響しません。上司からボタンを押すように指示された場合は、タスクを実行するために必要なすべての情報をすでに持っています。
プログラミングの世界では、ポリモーフィズムを使用して、アプリケーションをよりモジュール化して拡張可能にします。さまざまなアクションのコースを説明する厄介な条件ステートメントの代わりに、ニーズに基づいて選択する交換可能なオブジェクトを作成します。それがポリモーフィズムの基本的な目標です。
もし誰かがこれらの人々にCUTを言ったら
何が起こるか?
したがって、上記の表現は、OOPにおけるポリモーフィズム(同じ名前、異なる動作)とは何かを示しています。
面接に行くときに、面接官から、私たちが座っているのと同じ部屋で、多型のライブ例を教えて/見せてほしいと言われたら、
回答-ドア/窓
どのように疑問に思いますか?
ドア/窓を通して-人が来ることができる、空気が来ることができる、光が来ることができる、雨が来ることができる、など。
それをよりよく理解するために、私は上記の例を使用しました。コードの参照が必要な場合は、上記の回答に従ってください。
.foo()
メソッドがある場合、共通のインターフェースを共有する必要があると考える可能性があるため、これは良い例ではないと思います。ただし、これは真実ではなく、誤った抽象化につながります。インターフェースは、実行される役割を定義する必要があります。これには多くの異なる実装がある場合がありますが、すべて同じ入力のセットからプルし、同じ出力のセットから何かを返します。x.cut(...)
外科医、スタイリスト、俳優のへの入力は同じではなく、どちらも出力ではありません。
アメリカ合衆国大統領は多態性を採用しています。どうやって?まあ、彼は多くのアドバイザーを持っています:
全員が1つのことに責任を負うべきです:例:
大統領は亜鉛コーティングや量子物理学の専門家ではありません。彼は多くのことを知っていませんが、知っていることは1つだけです。国の運営方法です。
それはコードと少し同じです:懸念と責任は関連するクラス/人々に分けられるべきです。そうでなければ、あなたは大統領に文字通り世界のすべてを知っているでしょう-ウィキペディア全体。ウィキペディア全体をコードのクラスに含めることを想像してください。維持するのは悪夢です。
大統領がこれらすべての特定のことを知るのはなぜ悪い考えなのでしょうか。
大統領が具体的に何をすべきかを伝えるとしたら、それは大統領が何をすべきかを正確に知る必要があることを意味します。大統領が特定のことを自分で知る必要がある場合、つまり、変更を加える必要がある場合は、1か所ではなく2か所で行う必要があります。
たとえば、EPAが汚染法を変更した場合、それが発生すると、EPAクラスと大統領クラスも変更する必要があります。1箇所ではなく2箇所でコードを変更するのは危険な場合があります。保守がはるかに難しいためです。
より良いアプローチはありますか?
より良いアプローチがあります:大統領は何かの詳細を知る必要はありません-彼はそれらのことをするために特に任命された人々から最高のアドバイスを要求することができます。
彼は国を運営するために多態的なアプローチを使うことができます。
例-多態的なアプローチの使用:
大統領がすることはすべて、人々に彼に助言するように頼むことです-そしてそれは実際に彼が実際に行うことです-そしてそれは良い大統領がすべきことです。彼の顧問はすべて異なった反応をしますが、彼らは皆、大統領が何を意味するかを知っています:Advise()。彼のオフィスには何百人もの人々がストリーミングしています。実際に彼らが誰であるかは問題ではありません。大統領が知っているのは、彼に彼らに「助言する」ように頼むとき、彼らはそれに応じてどのように対応するかを知っているということです。
public class MisterPresident
{
public void RunTheCountry()
{
// assume the Petraeus and Condi classes etc are instantiated.
petraeus.Advise(); // # Petraeus says send 100,000 troops to Fallujah
condolezza.Advise(); // # she says negotiate trade deal with Iran
healthOfficials.Advise(); // # they say we need to spend $50 billion on ObamaCare
}
}
このアプローチにより、大統領は軍事的な事柄、ヘルスケア、国際外交について何も知らずに文字通り国を運営することができます。詳細は専門家に任されています。大統領が知っておくべき唯一のことは、「Advise()」です。
望まないこと:
public class MisterPresident
{
public void RunTheCountry()
{
// people walk into the Presidents office and he tells them what to do
// depending on who they are.
// Fallujah Advice - Mr Prez tells his military exactly what to do.
petraeus.IncreaseTroopNumbers();
petraeus.ImproveSecurity();
petraeus.PayContractors();
// Condi diplomacy advice - Prez tells Condi how to negotiate
condi.StallNegotiations();
condi.LowBallFigure();
condi.FireDemocraticallyElectedIraqiLeaderBecauseIDontLikeHim();
// Health care
healthOfficial.IncreasePremiums();
healthOfficial.AddPreexistingConditions();
}
}
番号!番号!番号!上記のシナリオでは、大統領はすべての作業を行っています。彼は部隊の数の増加と既存の状況について知っています。これは、中東の政策が変化した場合、大統領はペトレウス階級だけでなく、彼の命令も変更しなければならないことを意味します。大統領がそのような細部に行き詰まる必要はないはずなので、ペトラエウスのクラスを変更するだけでよい。彼は詳細について知る必要はありません。彼が知る必要があるのは、彼が1つの注文をした場合、すべてが面倒を見るということです。詳細はすべて専門家に委ねるべきです。
これにより、大統領は自分の最善を尽くすことができます。一般的なポリシーを設定し、見栄えをよくして、ゴルフをする:P。
要するに、これは多態性です。どのように正確に行われますか?「共通インターフェースの実装」を通じて、または基本クラス(継承)を使用して、これをより明確に説明する上記の回答を参照してください。(この概念をより明確に理解するには、インターフェースとは何かを理解する必要があり、継承とは何かを理解する必要があります。それがなければ、苦労するかもしれません。)
言い換えると、Petraeus、Condi、HealthOfficialsはすべて「インターフェースを実装する」クラスになります-それをIAdvisor
1つのメソッドだけを含むインターフェースと呼びましょうAdvise()
。しかし、今は詳細に入る。
これは理想的です
public class MisterPresident
{
// You can pass in any advisor: Condi, HealthOfficials,
// Petraeus etc. The president has no idea who it will
// be. But he does know that he can ask them to "advise"
// and that's all Mr Prez cares for.
public void RunTheCountry(IAdvisor governmentOfficer)
{
governmentOfficer.Advise();
}
}
public class USA
{
MisterPresident president;
public USA(MisterPresident president)
{
this.president = president;
}
public void ImplementPolicy()
{
IAdvisor governmentOfficer = getAdvisor(); // Returns an advisor: could be condi, or petraus etc.
president.RunTheCountry(governmentOfficer);
}
}
あなたが本当に知る必要があるすべてはこれです:
お役に立てれば幸いです。何もわからない場合はコメントを投稿してください。もう一度やります。
if healthAdvisor? then do this:
そしてif petraus then do that etc.
、このパターンが繰り返される必要があります、それはに、不要なと複雑です。上記の編集を参照してください。
ポリモーフィズムとは、オブジェクトのクラスを親クラスであるかのように扱う機能です。
たとえば、Animalというクラスと、Animalを継承するDogというクラスがあるとします。ポリモーフィズムは、次のように任意のDogオブジェクトをAnimalオブジェクトとして扱う機能です。
Dog* dog = new Dog;
Animal* animal = dog;
classes have different functionality while sharing a common interface
ポリモーフィズム:
これはオブジェクト指向プログラミングの概念です。異なるオブジェクトがそれぞれ独自の方法で同一のメッセージに応答する能力は、ポリモーフィズムと呼ばれます。
ポリモーフィズムは、すべてのクラスが独自の名前空間に存在するという事実から生じます。クラス定義内で割り当てられた名前は、その外部で割り当てられた名前と競合しません。これは、オブジェクトのデータ構造のインスタンス変数とオブジェクトのメソッドの両方に当てはまります。
C構造体のフィールドが保護された名前空間にあるように、オブジェクトのインスタンス変数もそうです。
メソッド名も保護されています。C関数の名前とは異なり、メソッド名はグローバルシンボルではありません。1つのクラスのメソッドの名前は、他のクラスのメソッド名と競合することはできません。2つのまったく異なるクラスが、同じ名前のメソッドを実装できます。
メソッド名はオブジェクトのインターフェースの一部です。オブジェクトが何かをするように要求するメッセージが送信されると、メッセージはオブジェクトが実行するメソッドを指定します。異なるオブジェクトは同じ名前のメソッドを持つことができるため、メッセージの意味は、メッセージを受信する特定のオブジェクトに関連して理解する必要があります。2つの異なるオブジェクトに同じメッセージを送信すると、2つの異なるメソッドを呼び出すことができます。
ポリモーフィズムの主な利点は、プログラミングインターフェースが簡素化されることです。クラスごとにクラスで再利用できる規則を確立できます。プログラムに追加する新しい関数ごとに新しい名前を作成する代わりに、同じ名前を再利用できます。プログラミングインターフェイスは、それらを実装するクラスとは別に、一連の抽象的な動作として説明できます。
例:
例1:Python 2.xで記述された簡単な例を次に示します。
class Animal:
def __init__(self, name): # Constructor of the class
self.name = name
def talk(self): # Abstract method, defined by convention only
raise NotImplementedError("Subclass must implement abstract method")
class Cat(Animal):
def talk(self):
return 'Meow!'
class Dog(Animal):
def talk(self):
return 'Woof! Woof!'
animals = [Cat('Missy'),
Dog('Lassie')]
for animal in animals:
print animal.name + ': ' + animal.talk()
例2:ポリモーフィズムは、メソッドのオーバーロードとメソッドのオーバーライドの概念を使用してJavaで実装されます。
ポリモーフィズムを議論するための車の例を考えてみましょう。フォード、ホンダ、トヨタ、BMW、ベンツなどのあらゆるブランドを取りましょう。すべてがタイプの車です。
しかし、それぞれに独自の高度な機能と、より高度なテクノロジーがあり、移動動作に関与しています。
次に、基本タイプのCarを作成します
Car.java
public class Car {
int price;
String name;
String color;
public void move(){
System.out.println("Basic Car move");
}
}
フォードカーの例を実装してみましょう。
FordはCar型を拡張して、そのすべてのメンバー(プロパティとメソッド)を継承します。
Ford.java
public class Ford extends Car{
public void move(){
System.out.println("Moving with V engine");
}
}
上記のFordクラスはCarクラスを拡張し、move()メソッドも実装します。moveメソッドはInheritanceを通じてFordですでに使用可能ですが、Fordは独自の方法でメソッドを実装しています。これはメソッドのオーバーライドと呼ばれます。
Honda.java
public class Honda extends Car{
public void move(){
System.out.println("Move with i-VTEC engine");
}
}
ちょうどフォードのように、ホンダも車のタイプを拡張し、独自の方法で移動メソッドを実装しました。
メソッドのオーバーライドは、ポリモーフィズムを有効にするための重要な機能です。メソッドのオーバーライドを使用すると、サブタイプは、継承を通じて利用できるメソッドの動作方法を変更できます。
PolymorphismExample.java
public class PolymorphismExample {
public static void main(String[] args) {
Car car = new Car();
Car f = new Ford();
Car h = new Honda();
car.move();
f.move();
h.move();
}
}
ポリモーフィズムの出力例:
PolymorphismExampleクラスのメインメソッドで、Car、Ford、Hondaの3つのオブジェクトを作成しました。3つのオブジェクトはすべて、Carタイプで参照されます。
ここで重要な点に注意してください。スーパークラスタイプはオブジェクトのサブクラスタイプを参照できますが、その逆は不可能です。その理由は、継承を使用してスーパークラスのすべてのメンバーがサブクラスで利用可能であり、コンパイル時に、使用している参照型にアクセスしようとしているメソッドがあるかどうかをコンパイラが評価しようとするためです。
したがって、PolymorphismExampleの参照car、fおよびhの場合、moveメソッドはCarタイプから存在します。したがって、コンパイラは問題なくコンパイルプロセスをパスします。
しかし、ランタイム実行に関しては、仮想マシンはサブタイプであるオブジェクトのメソッドを呼び出します。したがって、メソッドmove()はそれぞれの実装から呼び出されます。
したがって、すべてのオブジェクトはCarタイプですが、実行時の実行は、呼び出しが発生するオブジェクトに依存します。これはポリモーフィズムと呼ばれます。
通常、これはタイプAのオブジェクトがタイプBのオブジェクトのように動作する機能を指します。オブジェクト指向プログラミングでは、これは通常、継承によって実現されます。続きを読むためのウィキペディアのリンク:
編集:壊れたリンクを修正しました。
classes have different functionality while sharing a common interface
ポリモーフィズムはこれです:
class Cup {
int capacity
}
class TeaCup : Cup {
string flavour
}
class CoffeeCup : Cup {
string brand
}
Cup c = new CoffeeCup();
public int measure(Cup c) {
return c.capacity
}
特定のインスタンスの代わりにカップだけを渡すことができます。各カップタイプごとに特定のmeasure()インスタンスを提供する必要がないため、これは一般的に役立ちます。
私はこれが良い答えの多い古い質問であることを知っていますが、1文の回答を含めたいです。
派生型を基本型であるかのように扱う。
上記の例はたくさんありますが、これは簡潔な答えだと思います。
(私はまったく異なる何かについて別の記事を閲覧していました。そして、ポリモーフィズムがポップアップしました...今、私はポリモーフィズムが何であるかを知っていたと思いましたが...まだそれを共有します...)
http://www.eioba.com/a/1htn/how-i-explained-rest-to-my-wife
この部分から読んでください:
.....ポリモーフィズム。これは、さまざまな名詞に同じ動詞を適用できるという、マニアックな言い方です。
一般的に言えば、同じまたは表面的に類似したAPIを使用して、多数の異なるタイプのオブジェクトをインターフェースする機能です。さまざまな形式があります。
関数のオーバーロード:sqrt(float)、sqrt(double)、sqrt(complex)など、同じ名前と異なるパラメーター型を持つ複数の関数を定義します。これを許可するほとんどの言語では、コンパイラーは渡される引数のタイプに応じて正しいものを自動的に選択するため、これはコンパイル時のポリモーフィズムです。
OOPの仮想メソッド:クラスのメソッドは、そのサブクラスの詳細に合わせて調整されたさまざまな実装を持つことができます。これらはそれぞれ、基本クラスで指定された実装をオーバーライドすると言われています。基本クラスまたはそのサブクラスのオブジェクトである可能性がある場合、正しい実装がその場で選択されるため、これは実行時のポリモーフィズムです。
テンプレート:一部のオブジェクト指向言語の機能で、関数、クラスなどを型でパラメーター化できます。たとえば、一般的な「リスト」テンプレートクラスを定義し、「整数のリスト」、「文字列のリスト」、「文字列のリストのリスト」などとしてインスタンス化できます。通常、任意の要素タイプのデータ構造に対してコードを1回記述し、コンパイラーはさまざまな要素タイプに対してそのバージョンを生成します。
ポリモーフィズムという用語の由来は次のとおりです。
ポリ=多く
モーフィズム=変化する能力
プログラミングでは、ポリモーフィズムは、オブジェクトを複数のタイプのものとして「見る」ことができる「技術」です。例えば:
生徒オブジェクトは人物オブジェクトでもあります。学生を「見る」(つまりキャストする)場合は、おそらく学生IDを要求できます。あなたはいつも人とそれをすることはできませんよね?(人は必ずしも学生ではないため、学生IDがない場合があります)。しかし、人はおそらく名前を持っています。学生もそうです。
結論として、異なる「角度」から同じオブジェクトを「見る」と、異なる「視点」(つまり、異なるプロパティまたはメソッド)が得られます。
したがって、この手法では、さまざまな角度から「見る」ことができるものを構築できます。
なぜポリモーフィズムを使用するのですか?手始めに…抽象化。この時点でそれは十分な情報であるはずです:)
類推を使ってみましょう。与えられた音楽台本に対して、それを演奏するすべてのミュージシャンは、解釈に彼女自身のタッチを与えます。
ミュージシャンはインターフェイスで抽象化できます。ミュージシャンが属するジャンルは、解釈のグローバルルールを定義する抽象クラスにすることができ、演奏するすべてのミュージシャンは具象クラスでモデル化できます。
あなたが音楽作品のリスナーである場合、スクリプトへの参照があります。たとえば、バッハの「フーガとトカタ」であり、それを実行するすべてのミュージシャンは独自の方法で多態性を示します。
これは、可能な設計の例(Javaの場合)です。
public interface Musician {
public void play(Work work);
}
public interface Work {
public String getScript();
}
public class FugaAndToccata implements Work {
public String getScript() {
return Bach.getFugaAndToccataScript();
}
}
public class AnnHalloway implements Musician {
public void play(Work work) {
// plays in her own style, strict, disciplined
String script = work.getScript()
}
}
public class VictorBorga implements Musician {
public void play(Work work) {
// goofing while playing with superb style
String script = work.getScript()
}
}
public class Listener {
public void main(String[] args) {
Musician musician;
if (args!=null && args.length > 0 && args[0].equals("C")) {
musician = new AnnHalloway();
} else {
musician = new TerryGilliam();
}
musician.play(new FugaAndToccata());
}
AnnHalloway
そしてVictorBorga
、それらはクラスではなくオブジェクトであるべきだと感じます-あなたの例は、例えば、public class Pianist implements Musician
そして、victorBorge = new Pianist();
など
別の質問のために、ポリモーフィズムの概要を提供しました。
それが役に立てば幸い。抽出...
...簡単なテストと[ポリモーフィズム]の定義から始めるのに役立ちます。コードを考えてみましょう:
Type1 x;
Type2 y;
f(x);
f(y);
ここで
f()
は、いくつかの操作を実行し、値x
とy
入力が与えられています。ポリモーフィックであるためにf()
は、少なくとも2つの異なる型(例:int
とdouble
)の値を操作して、型に適したコードを見つけて実行できる必要があります。
(C ++のポリモーフィズムに続く)
ポリモーフィズムは、オブジェクトがさまざまな形をとる能力です。OOPでのポリモーフィズムの最も一般的な使用法は、親クラス参照を使用して子クラスオブジェクトを参照する場合に発生します。Javaで作成されたこの例では、3つのタイプの車両があります。3つの異なるオブジェクトを作成し、wheelsメソッドを実行してみます。
public class PolymorphismExample {
public static abstract class Vehicle
{
public int wheels(){
return 0;
}
}
public static class Bike extends Vehicle
{
@Override
public int wheels()
{
return 2;
}
}
public static class Car extends Vehicle
{
@Override
public int wheels()
{
return 4;
}
}
public static class Truck extends Vehicle
{
@Override
public int wheels()
{
return 18;
}
}
public static void main(String[] args)
{
Vehicle bike = new Bike();
Vehicle car = new Car();
Vehicle truck = new Truck();
System.out.println("Bike has "+bike.wheels()+" wheels");
System.out.println("Car has "+car.wheels()+" wheels");
System.out.println("Truck has "+truck.wheels()+" wheels");
}
}
結果は次のとおりです。
詳細については、https://github.com/m-vahidalizadeh/java_advanced/blob/master/src/files/PolymorphismExample.javaにアクセスしてください。お役に立てば幸いです。
ポリモーフィズムとは、オブジェクトのニーズに応じて、オブジェクトの種類ごとに異なる処理を実行する同じ名前のメソッドをプログラマが作成する機能です。たとえば、と呼ばれるクラスとFraction
と呼ばれるクラスを開発している場合ComplexNumber
、どちらにもと呼ばれるメソッドが含まれている可能性がありますdisplay()
が、それぞれが異なる方法でそのメソッドを実装します。たとえば、PHPでは、次のように実装します。
// Class definitions
class Fraction
{
public $numerator;
public $denominator;
public function __construct($n, $d)
{
// In real life, you'd do some type checking, making sure $d != 0, etc.
$this->numerator = $n;
$this->denominator = $d;
}
public function display()
{
echo $this->numerator . '/' . $this->denominator;
}
}
class ComplexNumber
{
public $real;
public $imaginary;
public function __construct($a, $b)
{
$this->real = $a;
$this->imaginary = $b;
}
public function display()
{
echo $this->real . '+' . $this->imaginary . 'i';
}
}
// Main program
$fraction = new Fraction(1, 2);
$complex = new ComplexNumber(1, 2);
echo 'This is a fraction: '
$fraction->display();
echo "\n";
echo 'This is a complex number: '
$complex->display();
echo "\n";
出力:
This is a fraction: 1/2
This is a complex number: 1 + 2i
他の回答のいくつかは、ポリモーフィズムが継承と組み合わせてのみ使用されることを暗示しているようです。例えば、多分Fraction
とComplexNumber
呼ばれる抽象クラス実装の両方のNumber
方法があるdisplay()
両方の実施を義務付けている分数や複素数を、。しかし、あなたは必要ありません、ポリモーフィズムを利用するために継承。
少なくともPHPのような動的に型付けされた言語(C ++やJavaについては知りません)では、ポリモーフィズムにより、開発者は必ずしもオブジェクトの型を事前に知る必要がなく、メソッドの正しい実装が呼ばれる。たとえば、ユーザーがNumber
作成されたタイプを選択するとします。
$userNumberChoice = $_GET['userNumberChoice'];
switch ($userNumberChoice) {
case 'fraction':
$userNumber = new Fraction(1, 2);
break;
case 'complex':
$userNumber = new ComplexNumber(1, 2);
break;
}
echo "The user's number is: ";
$userNumber->display();
echo "\n";
この場合、display()
開発者がユーザーが分数と複素数のどちらを選択するかを事前に知ることができない場合でも、適切なメソッドが呼び出されます。
OOPでのポリモーフィズムとは、クラスが異なる型を持つ可能性があることを意味します。継承は、ポリモーフィズムを実装する1つの方法です。
たとえば、Shapeはインターフェイスであり、Square、Circle、Diamondのサブタイプがあります。これでSquareオブジェクトができました。SquareはShapeなので、SquareをShapeに自動的にアップキャストできます。ただし、ShapeをSquareにダウンキャストする場合は、明示的な型キャストを行う必要があります。ShapeがSquareであるとは言えないため、Circleの場合もあります。したがってSquare s = (Square)shape
、のようなコードを使用して手動でキャストする必要があります。形状がCircleの場合、java.lang.ClassCastException
CircleはSquareではないため、結果はになります。
ポリモーフィズムは、指定されたクラスでオブジェクトを使用する機能です。オブジェクトを構成するすべてのコンポーネントは、指定されたクラスのサブクラスによって継承されます。つまり、このオブジェクトがクラスによって宣言されると、そのオブジェクトの下のすべてのサブクラス(およびそのサブクラスなど)は、オブジェクトとそのコンポーネント(メイクアップ)を継承します。
各クラスは個別のファイルに保存する必要があることに注意してください。
次のコードは、ポリモーフィズムの例です。
スーパークラス:
public class Parent {
//Define things that all classes share
String maidenName;
String familyTree;
//Give the top class a default method
public void speak(){
System.out.println("We are all Parents");
}
}
父親、サブクラス:
public class Father extends Parent{
//Can use maidenName and familyTree here
String name="Joe";
String called="dad";
//Give the top class a default method
public void speak(){
System.out.println("I am "+name+", the father.");
}
}
子、別のサブクラス:
public class Child extends Father {
//Can use maidenName, familyTree, called and name here
//Give the top class a default method
public void speak(){
System.out.println("Hi "+called+". What are we going to do today?");
}
}
実行メソッドは、開始するために親クラスを参照します。
public class Parenting{
public static void main(String[] args) {
Parent parents = new Parent();
Parent parent = new Father();
Parent child = new Child();
parents.speak();
parent.speak();
child.speak();
}
}
各クラスは個別の* .javaファイルで宣言する必要があることに注意してください。コードはコンパイルされるはずです。また、さらに下でmaidenNameとfamilyTreeを継続的に使用できることにも注意してください。それがポリモーフィズムの概念です。ここでは、継承の概念についても説明します。1つのクラスを使用するか、サブクラスでさらに定義します。
これが役立ち、明確になることを願っています。コードの検証に使用できるコンピューターが見つかったら、結果を投稿します。お待ちいただきありがとうございます。
ポリモーフィズムは、同じルーチン(関数、メソッド)が異なる型に作用することを可能にします。
多くの既存の回答では、サブタイプとポリモーフィズムが混同されているため、ポリモーフィズムを実装する3つの方法(サブタイプを含む)を次に示します。
以下も参照してください。
http://wiki.c2.com/?CategoryPolymorphism
https://en.wikipedia.org/wiki/Polymorphism_(computer_science)
ポリモーフィズムは、あるモジュールを作成して別のモジュールを呼び出す機能を提供しますが、制御のフローではなく、制御のフローに対するコンパイル時の依存ポイントを持っています。
ポリモーフィズムを使用することにより、高レベルモジュールは低レベルモジュールに依存しません。どちらも抽象化に依存しています。これは、依存関係の逆転の原則を適用するのに役立ちます(https://en.wikipedia.org/wiki/Dependency_inversion_principle)。
これが私が上記の定義を見つけた場所です。ビデオの約50分前に、インストラクターが上記について説明します。 https://www.youtube.com/watch?v=TMuno5RZNeE
ポリモーフィズムとは、次の機能です。
特殊化された型のメソッドを呼び出すときに、その一般化された型を知っているだけで、特殊化された型のインスタンスで操作を呼び出します。これは、動的な多態性です。
保存名はあるが異なるパラメーターを持ついくつかのメソッドを定義します。これは静的なポリモーフィズムです。
最初の場合は歴史的な定義と最も重要です。
これにより、クラス階層の強く型付けされた一貫性を作成し、異なるタイプのオブジェクトのリストを、それらのタイプを知らずに親タイプの1つだけだけでなく、データバインディングとして管理するなど、いくつかの魔法のようなことを行うことができます。
ポイント、ライン、四角形、円などのシェイプは、操作Draw()が何も受け取らないか、パラメータを消去してタイムアウトを設定します。
public class Shape
{
public virtual void Draw()
{
DoNothing();
}
public virtual void Draw(int timeout)
{
DoNothing();
}
}
public class Point : Shape
{
int X, Y;
public override void Draw()
{
DrawThePoint();
}
}
public class Line : Point
{
int Xend, Yend;
public override Draw()
{
DrawTheLine();
}
}
public class Rectangle : Line
{
public override Draw()
{
DrawTheRectangle();
}
}
var shapes = new List<Shape> { new Point(0,0), new Line(0,0,10,10), new rectangle(50,50,100,100) };
foreach ( var shape in shapes )
shape.Draw();
ここで、ShapeクラスとShape.Draw()メソッドを抽象としてマークする必要があります。
彼らは理解するためのものではありません。
ポリモーフィズムがなく、abstract-virtual-overrideを使用して、形状を解析しているとき、CLRが呼び出すメソッドがわからないため、呼び出されるのはSpahe.Draw()メソッドだけです。したがって、処理対象の型のメソッドを呼び出します。リスト宣言のため、ここでは型はShapeです。したがって、コードはまったく何もしません。
ポリモーフィズムを使用すると、CLRは、仮想テーブルと呼ばれるものを使用して、操作対象のオブジェクトの実際のタイプを推測できます。だからそれは良いメソッドメソッドを ShapeがPointの場合はShape.Draw()を呼び出して、Point.Draw()を呼び出します。したがって、コードは形状を描画します。