37

親クラスとその子を持つ次のコードがあります。私は、コードがポリモーフィズムを使用することでどのように利益を得るかを判断しようとしています。

class FlyingMachines {
    public void fly() {
        System.out.println("No implementation");
    }
}

class Jet extends FlyingMachines {
    public void fly() {
        System.out.println("Start, Taxi, Fly");
    }

    public void bombardment() {
        System.out.println("Throw Missile");
    }
}

public class PolymorphicTest {
    public static void main(String[] args) {
        FlyingMachines flm = new Jet();
        flm.fly();

        Jet j = new Jet();
        j.bombardment();
        j.fly();
    }
}

flm.fly()両方とも同じ答えを私にj.fly()与えるとき、ポリモーフィズムの利点は何ですか?

4

13 に答える 13

51

あなたの例では、のサブクラスが1つしかないため、ポリモーフィズムの使用はそれほど役に立ちませんFlyingMachine。ポリモーフィズムは、複数の種類がある場合に役立ちますFlyingMachine。次に、あらゆる種類を受け入れ、FlyingMachineそのメソッドを使用するメソッドを作成できfly()ます。例としてはtestMaxAltitude(FlyingMachine)

ポリモーフィズムでのみ利用できるもう1つの機能は、を持ってそれを使用して、、、またはList<FlyingMachine>を格納する機能です。JetKiteVerySmallPebbles

ポリモーフィズムを使用するために作成できる最良のケースの1つは、実装ではなくインターフェースを参照する機能です。

たとえば、。List<FlyingMachine>ではなくasを返すメソッドを使用することをお勧めしますArrayList<FlyingMachine>。そうすれば、メソッドを使用するコードを壊すことなく、メソッド内の実装をaLinkedListまたはaに変更できます。Stack

于 2012-06-16T14:49:24.457 に答える
27

flm.fly()両方とも同じ答えを私にj.fly() 与えるとき、ポリモーフィズムの利点は何ですか?

利点は

FlyingMachines flm = new Jet();
flm.fly();

戻り値

"Start, Taxi, Fly"

それ以外の

"No implementation"

それがポリモーフィズムです。fly()タイプのオブジェクトを呼び出すFlyingMachineと、それが実際にはaであることがわかり、を出力する間違ったメソッドではなくJet、適切なメソッドを呼び出します。fly()"No implementation"

つまり、タイプのオブジェクトを処理するメソッドを記述し、またはFlyingMachineのようなすべての種類のサブタイプをフィードすることができます。これらのメソッドは常に正しいことを行います。つまり、常に同じことを行うのではなく、適切なタイプのメソッドを呼び出すこと、つまり出力します。JetHelicopterfly()"No implementation".

ポリモーフィズム

あなたの例では、ポリモーフィズムは役に立ちません。

  • a)さまざまなタイプのオブジェクトがあり、それらがすべて同じAPIに準拠しているため、それらすべてのさまざまなタイプで機能するクラスを記述できる場合に役立ちます。

  • FlyingMachineb)既存のロジックを変更せずに、アプリケーションに新しいを追加できる場合にも役立ちます。

a)とb)は同じコインの両面です。

その方法をお見せしましょう。

コード例

import java.util.ArrayList;
import java.util.List;

import static java.lang.System.out;

public class PolymorphismDemo {

    public static void main(String[] args) {
        List<FlyingMachine> machines = new ArrayList<FlyingMachine>();
        machines.add(new FlyingMachine());
        machines.add(new Jet());
        machines.add(new Helicopter());
        machines.add(new Jet());

        new MakeThingsFly().letTheMachinesFly(machines);
    }
}

class MakeThingsFly {
    public void letTheMachinesFly(List<FlyingMachine> flyingMachines) {
        for (FlyingMachine flyingMachine : flyingMachines) {
            flyingMachine.fly();
        }
    }
}

class FlyingMachine {
    public void fly() {
        out.println("No implementation");
    }
}

class Jet extends FlyingMachine {
    @Override
    public void fly() {
        out.println("Start, taxi, fly");
    }

    public void bombardment() {
        out.println("Fire missile");
    }
}

class Helicopter extends FlyingMachine {
    @Override
    public void fly() {
        out.println("Start vertically, hover, fly");
    }
}

説明

a)MakeThingsFlyクラスは、タイプがすべてのものを処理できますFlyingMachine

b)このメソッドletTheMachinesFlyは、新しいクラスを追加するときにも変更なしで機能します(!)。次に例を示しPropellerPlaneます。

public void letTheMachinesFly(List<FlyingMachine> flyingMachines) {
        for (FlyingMachine flyingMachine : flyingMachines) {
            flyingMachine.fly();
        }
    }
}

それがポリモーフィズムの力です。これを使用して、 open-closed-principleを実装できます。

于 2015-10-02T14:06:44.590 に答える
15

ポリモーフィズムを使用する理由は、同じインターフェイスで多数の異なるオブジェクトを取得する汎用フレームワークを構築する場合です。新しいタイプのオブジェクトを作成する場合、オブジェクトの「ルール」に従っている限り、新しいオブジェクトタイプに対応するためにフレームワークを変更する必要はありません。

したがって、あなたの場合、より有用な例は、さまざまなタイプのFlyingMachinesを受け入れるオブジェクトタイプ「Airport」を作成することです。空港は、次のような「AllowPlaneToLand」関数を定義します。

//pseudocode
void AllowPlaneToLand(FlyingMachine fm)
{
    fm.LandPlane();
}

FlyingMachineの各タイプが適切なLandPlaneメソッドを定義している限り、それ自体を適切に着陸させることができます。空港はFlyingMachineについて何も知る必要はありませんが、飛行機を着陸させるには、FlyingMachineでLandPlaneを呼び出す必要があります。そのため、空港を変更する必要がなくなり、ハンドグライダー、UFO、パラシュートなど、新しいタイプのFlyingMachinesを引き続き受け入れることができます。

したがって、ポリモーフィズムは、これらのオブジェクトを中心に構築され、変更することなくこれらのメソッドに一般的にアクセスできるフレームワークに役立ちます。

于 2012-06-16T15:04:01.703 に答える
10

最初にオブジェクト指向デザインを見てみましょう。継承はIS-A関係を表します。一般に、「FlyingMachines飛ばせ」のように言うことができます。すべての特定のFlyingMachines(サブクラス)IS-A FlyingMachines(親クラス)は、たとえばJet、この「飛ばせ」に適合しますFlyingMachinesが、この飛翔を実際に特定の(サブクラス)の飛翔関数にしたいのですが、それはポリモーフィズムが引き継ぎます。

したがって、私たちは抽象的な方法で物事を行い、指向性のあるインターフェースと基本クラスであり、実際には詳細な実装に依存しません。ポリモーフィズムは正しいことを行います!

于 2012-06-16T15:30:08.127 に答える
6

Javaでは、かなりの数の理由から、ポリモーフィズム(実行時とコンパイル時の両方)が必要です。

メソッドのオーバーライドは実行時のポリモーフィズムであり、オーバーロードはコンパイル時のポリモーフィズムです。

それらのいくつかはあります(それらのいくつかはすでに議論されています):

  1. コレクション:複数のタイプのフライングマシンがあり、それらすべてを1つのコレクションにまとめたいとします。タイプのリストを定義して、FlyingMachinesそれらすべてを追加するだけです。

    List<FlyingMachine> fmList = new ArrayList<>();
    fmList.add(new new JetPlaneExtendingFlyingMachine());
    fmList.add(new PassengerPlanePlaneExtendingFlyingMachine());
    

    上記は、ポリモーフィズムによってのみ実行できます。それ以外の場合は、2つの別々のリストを維持する必要があります。

  2. あるタイプを別のタイプにカーストする:次のようなオブジェクトを宣言します:

    FlyingMachine fm1 = new JetPlaneExtendingFlyingMachine();
    FlyingMachine fm2 = new PassengerPlanePlaneExtendingFlyingMachine();
    fm1 = fm2; //can be done
    
  3. オーバーロード:指定したコードとは関係ありませんが、オーバーロードはコンパイル時ポリモーフィズムと呼ばれる別のタイプのポリモーフィズムでもあります。

  4. タイプを受け入れる単一のメソッドでFlyingMachineすべてのタイプ、つまりFlyingMachineのサブクラスを処理できます。でのみ達成できますPolymorphism

于 2017-06-06T18:37:13.280 に答える
4

ジェット機だけを使用する場合はそれほど追加されません。飛行機など、さまざまなFlyingMachinesを使用する場合に利点があります。

より多くのクラスを含めるように変更したので、ポリモーフィズムの利点は、受け取るインスタンスの特定のタイプ(およびビジネスコンセプト)からの抽象化であり、それが飛ぶことができることを気にするだけです。

于 2012-06-16T14:52:28.617 に答える
3

インスタンスのタイプは実際には同じであるため、両方ともflm.fly()同じ答えを返します。つまり、同じように動作します。j.fly()Jet

次の場合に違いがわかります。

FlyingMachines flm = new FlyingMachines();
flm.fly();

Jet j = new Jet();
j.bombarment();
j.fly();

ポリモーフィズムは、動作が異なる同じメソッドシグネチャとして定義されます。ご覧のとおり、との両方FlyingMachinesJetメソッドfly()が定義されていますが、メソッドの実装は異なり、動作も異なると見なされます。

aaを参照してください

于 2012-06-16T14:51:36.010 に答える
3

ポリモーフィズムは、本番レベルのコードを生成することを目的とした「if」条件をコードで削除するのにも役立ちます。条件を削除すると、コードの可読性が向上し、より良いユニットテストケースを作成できるためです。 !(n階乗)可能性。

どのように見てみましょう

FlyingMachineクラスがあり、FlyMachineのタイプを以下のように定義するコンストラクターで文字列を受け取る場合

class FlyingMachine{

    private type;

    public FlyingMachine(String type){
             this.type = type;
    }

    public int getFlyingSpeedInMph {
         if(type.equals("Jet"))
              return 600;
         if(type.equals("AirPlane"))
              return 300;
    }

 }

FlyingMachineの2つのインスタンスを次のように作成できます。

 FlyingMachine jet = new FlyingMachine("Jet");
 FlyingMachine airPlane = new FlyingMachine("AirPlane");

を使用して速度を取得します

 jet.fylingSpeedInMph();
 airPlane.flyingSpeedInMph();

ただし、ポリモーフィズムを使用する場合は、一般的なFlyMachineクラスを拡張し、以下のようにgetFlyingSpeedInMphをオーバーライドすることで、if条件を削除します。

class interface FlyingMachine {

     public int abstract getFlyingSpeedInMph;
}


class Jet extends FlyingMachine {
    @Override
    public int getFlyingSpeedInMph(){
          return 600;
    }
}

class Airplane extends FlyingMachine {
    @Override
    public int getFlyingSpeedInMph(){
          return 600;
    }
}

今、あなたは以下のように飛行速度を得ることができます

 FlyingMachine jet = new Jet();
 jet.flyingSpeed();

 FlyingMachine airPlane = new AirPlane();
 airPlane.flyingSpeed();
于 2016-12-03T13:39:30.377 に答える
3

これにもう1つのクラスを追加しましょう。これは、ポリモーフィズムの使用法を理解するのに役立ちます。

class FlyingMachines {
    public void fly() {
        System.out.println("No implementation");
    }
}

class Jet extends FlyingMachines {
    public void fly() {
        System.out.println("Start, Jet, Fly");
    }
}

class FighterPlan extends FlyingMachines {
    public void fly() {
        System.out.println("Start, Fighter, Fight");
    }
}

public class PolymorphicTest {
    public static void main(String[] args) {
        FlyingMachines flm = new Jet();
        flm.fly();

        FlyingMachines flm2 = new FighterPlan();
        flm2.fly();
    }
}

出力:

Start, Jet, Fly
Start, Fighter, Fight
于 2017-03-29T09:00:06.390 に答える
1

ポリモーフィズムは、ポリモーフィズムが必要な場合にのみメリットをもたらします。これは、概念プロジェクトのエンティティが別のエンティティの特殊化と見なされる場合に使用されます。主なアイデアは「専門化」です。優れた例は、たとえば生物に適用される、いわゆる分類法にあります。犬と人間はどちらも哺乳類です。これは、クラスMammalsが、いくつかのプロパティと動作に共通するすべてのエンティティをグループ化することを意味します。

また、ElectricCarとDieselCarは自動車の専門です。つまり、両方にisThereFuel()があります。これは、車を運転するときに、車を運転するのに十分な燃料があるかどうかを知る必要があるためです。もう一つの素晴らしいコンセプトは「期待」です。

ソフトウェアを起動する前に、ソフトウェアのドメインのER(エンティティ関係)図を描くことは常に素晴らしい考えです。これは、どの種類のエンティティが作成されるかを想像する必要があるためです。十分な能力があれば、エンティティ間の一般的な動作を見つけるコードを大幅に節約できます。しかし、コードを保存することだけが優れたプロジェクトのメリットではありません。

「クリーンコード」を書くことを可能にする技術と概念のコレクションである、いわゆる「ソフトウェアエンジニアリング」を見つけることに興味があるかもしれません(プログラムによって広く提案されている「クリーンコード」と呼ばれる素晴らしい本もあります) 。

于 2015-10-02T14:20:40.763 に答える
0

それ自体が明確に述べられているポリモーフィズムは、多くの人にマッピングされたものです。

javaはoops言語であるため、抽象化、オーバーロード、オーバーライドによる実装があります。

javaには実行時ポリモーフィズムの仕様がないことを忘れないでください。

それにもいくつかの最良の例があります。

public abstract class Human {

    public abstract String getGender();

}

class Male extends Human
{
    @Override
    public String getGender() {
        return "male";
    }
}

class Female extends Human
{
    @Override
    public String getGender() {
        return "female";
    }
}

オーバーライド

基本クラスの動作を再定義します。たとえば、ベースカーの既存の移動機能に速度カウントを追加したいとします。

オーバーロード

異なる署名を持つ同じ名前の動作を持つことができます。たとえば、特定の大統領ははっきりと大声で話しますが、別の大統領は大声でしか話しません。

于 2014-01-09T07:11:34.463 に答える
0

Javaでポリモーフィズムが必要な理由は、継承の実装でこの概念が広く使用されているためです。これは、異なる内部構造を持つオブジェクトが同じ外部インターフェイスを共有できるようにする上で重要な役割を果たします。

于 2014-04-13T05:49:55.403 に答える
0

ここで、この特定のコードでは、ポリモーフィズムは必要ありません。

ポリモーフィズムが必要な理由と時期を理解しましょう。

さまざまな種類の機械(車、スクーター、洗濯機、電気モーターなど)があり、すべての機械が起動および停止することがわかっているとします。ただし、マシンを起動および停止するロジックは、マシンごとに異なります。ここでは、マシンごとに開始と停止の実装が異なります。したがって、さまざまな実装を提供するには、ポリモーフィズムが必要です。

ここでは、メソッドとしてstart()とを使用する基本クラスのマシンを作成できます。stop()各マシンタイプは、この機能と@Overrideこれらのメソッドを拡張できます。

于 2018-05-17T14:21:28.117 に答える