私は今日、モジュールオープンブックテストの終わりにこの質問を受け、失くしたことに気づきました。私はHead first Java
を読んでいました、そして両方の定義は全く同じように見えました。私は、MAINの違いが私自身の心の中でどんなものなのか疑問に思いました。私はこれに似たような質問がいくつかあることを知っています、しかし私が決定的な答えを提供するのを見た人はいません。
継承は、「クラス」が既存の「クラス」から派生するときです。したがって、Person
クラスがある場合は、Student
を拡張するPerson
クラスがあり、Student
はすべてのものを継承します。 Person
があります。 Personのフィールド/メソッドに設定したアクセス修飾子に関する詳細はいくつかありますが、それが基本的な考え方です。たとえば、Person
にプライベートフィールドがある場合、そのプライベートフィールドとプライベートフィールドはサブクラスから見えないため、Student
には表示されません。
多態性は、プログラムにどのような種類のものがあるかに応じて、プログラムがどのメソッドを使用するかを決定する方法を扱います。 Person
メソッドを持つread
があり、Student
を拡張するPerson
がある場合、これにはread
の独自の実装があります。呼び出されるメソッドは、Person
またはStudent
のどちらがあるかによって、ランタイムによって決まります。それは少しトリッキーになります、しかしあなたがのような何かをするならば
Person p = new Student();
p.read();
Studentのreadメソッドが呼び出されます。多型の動作を確認します。 Student
はPerson
なので、この代入を行うことができますが、ランタイムはp
の実際の型が学生.
詳細は言語によって異なります。あなたは例えばJavaScriptで継承を行うことができますが、それはそれがJavaで動作する方法とは完全に異なります。
継承は、サブクラス内のスーパークラスの構造と動作を利用するを意味します。
多態性はサブクラス内のスーパークラスの動作の変更を意味します。
多態性:異なる種類のオブジェクトを同じように扱う能力。例:キリンとワニはどちらも動物で、動物はMove
をすることができます。 Animal
のインスタンスがある場合は、それがどんな種類の動物であるかを知らなくても気にせずにMove
を呼び出すことができます。
Inheritance:これは多態性とコードの再利用の両方を同時に達成する1つの方法です。
他の形態の多態性:多態性のみを提供し、コードの再利用を行わないインタフェースなど、多態性を実現する方法は他にもあります(SnakeのMove
など、コードがまったく異なる場合があります)犬のためのMove
とは全く違うでしょう。その場合、この場合にはインターフェースがより良い多形の選択になるでしょう。
他の動的言語では、Duck Typingを使ってポリモーフィズムを実現できます。これは、クラスが同じ基本クラスやインタフェースを共有する必要すらなく、同じ名前のメソッドが必要なだけです。あるいは、Javascriptのようにさらに動的であれば、クラスさえまったく必要なく、同じメソッド名を持つオブジェクトだけを多態的に使用できます。
主な違いは、多型が継承の特定の結果であるということです。ポリモーフィズムとは、呼び出されるメソッドがオブジェクトの型に基づいて実行時に決定される場所です。これは、あるクラスが別のクラスを継承し、特定のメソッドをオーバーライドしたときに発生する状況です。ただし、通常の継承ツリーでは、メソッドをオーバーライドする必要はないため、すべてのメソッド呼び出しを多態的にする必要はありません。それは理にかなっていますか?それはすべてのフォード車が自動車であるのと同様の問題ですが、すべての自動車がフォードであるわけではありません(とはいえ....).
さらに、ポリモーフィズムはメソッド呼び出しを扱いますが、継承はデータメンバーなども表します。
Javaでは、この2つは密接に関連しています。これは、Javaが「動的ディスパッチ」と呼ばれるメソッド呼び出しのための技法を使用しているためです。持っていれば
public class A {
public void draw() { ... }
public void spin() { ... }
}
public class B extends A {
public void draw() { ... }
public void bad() { ... }
}
...
A testObject = new B();
testObject.draw(); // calls B's draw, polymorphic
testObject.spin(); // calls A's spin, inherited by B
testObject.bad(); // compiler error, you are manipulating this as an A
それから、BはAからspin
を継承することがわかります。しかし、オブジェクトを型Aのように操作しようとすると、draw
に対するBの動作が得られます。 draw
の動作は多態的です。
いくつかの言語では、多態性と継承はそれほど密接に関連していません。たとえば、C++では、virtualと宣言されていない関数は継承されますが、動的にはディスパッチされません。そのため、継承を使用してもそのような多態性の動作は得られません。
JavaScriptでは、すべての関数呼び出しは動的にディスパッチされ、弱い型付けしかできません。これは、それぞれ独自のdraw
を持つ無関係なオブジェクトをたくさん用意し、それらを反復処理して関数を呼び出すことができ、それぞれが正常に動作することを意味します。あなたは、継承を必要とせずにあなた自身の多形性描画をするでしょう。
多態性:ペンを販売している会社で働いているとしましょう。それで、あなたはあなたがペンについて知る必要があるすべてを扱う「ペン」と呼ばれる非常に素晴らしいクラスを作ります。あなたはすべてPenクラスを使用して、請求書作成、発送、請求書作成のためのあらゆる種類のクラスを書きます。ある日ボスがやってきて、「素晴らしいニュースだ。会社は成長しており、私たちは今、本とCDを売っている!」と言う。すばらしいニュースではありません。Penを使用するすべてのクラスをBook&CDも使用するように変更する必要があるためです。しかし、あなたがもともと "SellableProduct"と呼ばれるインターフェースを作成し、Penがこのインターフェースを実装したとしたらどうでしょうか。そうすれば、Penの代わりにそのインターフェースを使用するために、配送、請求などのすべてのクラスを作成できたはずです。あとは、SellableProductインターフェースを実装するBook&CompactDiscという新しいクラスを作成するだけです。多態性のため、他のすべてのクラスは変更なしに機能し続けることができます。意味を成す?
だから、それは多相を実現するための方法の一つである継承を使用することを意味します。
多態性はクラス/インタフェース内で可能ですが、継承は常に2 OR個以上のクラス/インタフェース間で行われます。継承は常に「is-a」の関係に準拠していますが、多態性(「is-a」/「has-a」の両方の関係に準拠できる)とは必ずしも一致しません。
継承はより静的なもの(あるクラスが別のクラスを拡張するもの)であるのに対し、ポリモーフィズムは動的/実行時のものです(オブジェクトは静的/宣言型ではなく、動的/実行型に従って動作します)。
例えば。
// This assignment is possible because B extends A
A a = new B();
// polymorphic call/ access
a.foo();
- > aの静的/宣言型はAですが、実際の動的/実行時型はBなので、a.foo()はAではなくBで定義されているfooを実行します。
Oracleのドキュメントでその違いを正確に引用しています。
inheritance: クラスはすべてのスーパークラスからフィールドとメソッドを継承します。直接か間接か。 サブクラスは、それが継承するメソッドをオーバーライドすることも、継承するフィールドやメソッドを非表示にすることもできます。 (フィールドを隠すことは一般にプログラミングの慣習としては良くないことに注意してください。)
polymorphism:polymorphismは、生物や種がさまざまな形や段階を持つことができる生物学の原則を指します。この原則は、オブジェクト指向プログラミングやJava言語などの言語にも適用できます。 クラスのサブクラスは、独自の独自の動作を定義しながら、親クラスと同じ機能をいくつか共有できます。
多態性はフィールドには適用されません。
関連記事:
多態性は、似たような特性を持つオブジェクトの種類間で共通の動作を表現するためのアプローチです。また、オーバーライドによってこれらの特性のバリエーションを作成することもできます。継承は、オブジェクトが関係と抽象的振る舞いを表現するオブジェクト階層を通して、多態性を実現する方法です。多態性を実現する唯一の方法ではありません。プロトタイプは、継承とは異なる多型を表現するもう1つの方法です。 JavaScriptはプロトタイプを使用する言語の一例です。他にも方法があると思います。
継承はコードの再利用に関連する概念です。たとえば、Animal
という親クラスがあり、それに特定の属性とメソッド(この例ではmakeNoise()
とsleep()
)が含まれている場合、Dog
とCat
という2つの子クラスを作成します。犬と猫の両方が同じように眠りにつくので(私は思いますが)、親クラスDog
によって提供されるCat
およびAnimal
サブクラスのsleep()
メソッドに機能を追加する必要はありません。ただし、Dog
は鳴き声を上げ、Cat
は鳴り響きます。Animal
クラスにはノイズを鳴らすためのメソッドがあるかもしれませんが、犬と猫は互いの音や他の動物と音が違っています。したがって、その振る舞いをそれらの特定のタイプに対して再定義する必要があります。したがって、多型の定義。お役に立てれば。
多態性は、継承の効果です。それはお互いを拡張するクラスでのみ起こり得ます。クラスの正確な型を知らなくても、クラスのメソッドを呼び出すことができます。また、ポリモーフィズムは実行時にも起こります。
たとえば、Java多態性の例
継承により、派生クラスは基本クラスのインタフェースとコードを共有できます。これはコンパイル時に起こります。
たとえば、JavaプラットフォームのすべてのクラスはObjectの子孫です(画像提供:Oracle)。
Java継承 および Java polymorphism についてさらに学ぶために
継承は一種の多態性です。実際には、継承は動的多態性です。だから、あなたが継承を削除するとき、あなたはもう上書きすることはできません。
polymorphismの主な目的は、スーパークラスへの参照変数を作成し、サブクラス object =>オブジェクトが実行できるmultiple)行動。
継承、サブクラスはスーパークラスのプロパティを継承します。
継承は、クラスAがすべての親からObjectまで、静的でないすべてのprotected/publicメソッド/フィールドを継承するときです。
多態性はJava
内の継承によって実現されます。
public class Animal {}
public interface Herbivore {}
public interface Carnivore {}
public interface Pet {}
public class Hamster extends Animal implements Herbivore implements Pet () {}
public class Cat extends Animal implements Carnivore implements Pet () {}
Hamster
クラスはAnimal
、Herbivore
、Pet
から構造体を継承してペットの多態的行動主義.
Cat
クラスはAnimal
、Carnivore
およびPet
から構造体を継承して )ペットの多態性行動主義.
あなたがJavaを使うならば、それはこれと同じくらい簡単です:
ポリモーフィズムは、継承されたメソッドを使用していますが、異なる処理を行うためにそれらを「オーバーライド」しています(または、superを呼び出しても同じことが技術的にはポリモーフィックにはなりません)。
私が間違っていたら私を直してください。