ポリモーフィズムvsオーバーライドvsオーバーロード


347

Javaに関して、誰かが尋ねると:

ポリモーフィズムとは何ですか?

思いのオーバーロードまたはオーバーライド許容答えは?

それだけではない。

実装のないメソッドを定義した抽象基本クラスがあり、そのメソッドをサブクラスで定義した場合でも、それはオーバーライドされますか?

過負荷は確かに正しい答えではないと思います。


以下の回答は、ポリモーフィズムについて非常によく説明しています。しかし、私は、オーバーロードが一種の多態性であると言うことに強く反対します。それは、実際にオーバーロードに集中している質問と回答で正当化しようとしたのが多態性であるかどうかです。このスレッドにある@The Digital Gabegの回答を正当化しようとしました。詳細を参照:メソッドのオーバーロードは静的/コンパイル時のバインディングですが、ポリモーフィズムではありません。静的バインディングをポリモーフィズムと関連付けることは正しいですか?
PraveenKumar Lalasangi

回答:


894

ポリモーフィズムを表現する最も明確な方法は、抽象基本クラス(またはインターフェース)を使用することです

public abstract class Human{
   ...
   public abstract void goPee();
}

goPee()メソッドは人間には定義できないため、このクラスは抽象クラスです。これは、サブクラスMaleおよびFemaleに対してのみ定義可能です。また、人間は抽象的な概念です。男性でも女性でもない人間を作成することはできません。それはどちらかでなければなりません。

したがって、抽象クラスを使用して実装を延期します。

public class Male extends Human{
...
    @Override
    public void goPee(){
        System.out.println("Stand Up");
    }
}

そして

public class Female extends Human{
...
    @Override
    public void goPee(){
        System.out.println("Sit Down");
    }
}

今、私たちは人間でいっぱいの部屋全体に小便をするように言うことができます。

public static void main(String[] args){
    ArrayList<Human> group = new ArrayList<Human>();
    group.add(new Male());
    group.add(new Female());
    // ... add more...

    // tell the class to take a pee break
    for (Human person : group) person.goPee();
}

これを実行すると、次のようになります。

Stand Up
Sit Down
...

37
@yuudachi。私はクラスを教えるときにこの例を思いつきました。正規の「銀行口座」クラスは、基本クラスの「抽象度」を実際に表現していませんでした。他の標準的な例(動物、騒がしい)は、理解するには抽象的すぎました。サブクラスが明白すぎる単一のベースを探していました。実際、私が思いついたのは、性差別的でもステレオタイプ的でもない、goPee()だけです。(クラスでは、立ったり座ったりするのではなく、「左側のホールを降りる」と印刷しました。)
Chris Cudmore

100
この例はまた、生物学的システムを記述するために階層システムを使用する難しさをうまく強調しています。非常に若いおしっこなど、ほとんどすべての位置でおしっこをする人間もいます。一部の人間はインターセックスであり、「男性」または「女性」の生物学的ラベルはかなり不明確になります。社会的な意味はさらに複雑です。教育の例として、失禁またはインターセックスの誰か(たとえば、OOプログラミングの学生)が実際には人間ではないという含意など、モデリングの仮定が否定的な結果をもたらす可能性があることを示しています。
Andrew Dalke 2013

7
あなたの「男性でも女性でもない人間を作ることはできない」という論文に反論する少なくとも少数の人間を考えることができますが、それでもあなたのコードには当てはまります... ?;)
フランクW.ザメッティ2013

2
どのバージョンのgoPee()を呼び出すかは実行時にしか決定できないため、これは多態性のみであることを指摘することが重要だと思います。この例はそれを暗示していますが、それが正確に多態性である理由を指摘するのは良いことです。また、兄弟クラスは必要ありません。親子関係になることもあります。または、偶然にも同じ機能を持っている完全に無関係なクラスでさえあります。この例として、.toString()関数があります。どのオブジェクトでもランダムに呼び出すことができますが、コンパイラーはどのタイプのオブジェクトかを正確に知ることはできません。
Tor Valamo 2013

20
@AndrewDalke、生物学的複雑さに関するメモの場合は+1。また、goPee重力場を入力として取りません。このグローバルな状態への依存はユニットテストをCatheterizedIntersexAstronaut困難にし、サブクラス化が常に特性の構成に最適な方法であるとは限らないことを示しています。
マイクサミュエル

99

ポリモーフィズムとは、クラスインスタンスが、継承ツリー内の別のクラス(多くの場合、祖先クラスの1つ)のインスタンスであるかのように動作する機能です。たとえば、Javaでは、すべてのクラスがObjectから継承されます。したがって、Object型の変数を作成して、任意のクラスのインスタンスを割り当てることができます。

オーバーライド別のクラスから継承するクラスで発生する関数のタイプです。オーバーライド関数は、基本クラスから継承された関数を「置き換え」ますが、そのクラスのインスタンスがポリモーフィズムによって異なるタイプのふりをしている場合でも呼び出されるように置き換えます。前の例を参照すると、独自のクラスを定義して、toString()関数をオーバーライドできます。この関数はObjectから継承されているため、このクラスのインスタンスをObject型の変数にコピーすると、引き続き使用できます。通常、クラスがオブジェクトのふりをしているときにクラスでtoString()を呼び出すと、実際に起動するtoStringのバージョンは、オブジェクト自体で定義されたバージョンになります。ただし、関数はオーバーライドであるため、クラスインスタンスの場合でも、クラスのtoString()の定義が使用されます。

オーバーロードは、同じ名前でパラメータが異なる複数のメソッドを定義するアクションです。オーバーライドや多態性とは無関係です。


8
これは古いですが、ポリモーフィズムは、他のクラスが継承ツリーにある必要があることを意味しません。インターフェースが継承ツリーの一部であると見なす場合はJavaで行われますが、インターフェースが暗黙的に実装されるGoでは行われません。
JN

5
実際、ポリモーフィズムのためのクラスはまったく必要ありません。
StCredZero 2013

3
私は初心者です。間違っている場合は修正しますが、オーバーロードが多態性とは無関係であるとは言えません。少なくともJavaでは、ポリモーフィズムは呼び出し元のタイプに基づいて実装が選択される場合であり、オーバーロードはパラメータのタイプに基づいて実装が選択される場合ですよね。両者の類似点を見ると理解しやすくなります。
csjacobs24 2015年

9
不正解です。Ad hoc polymorphismあなたに説明するものであるオーバーロードセクションとある多型の場合。
ジョシーカルデロン

1
「オーバーライドや多態性とは無関係です。」このステートメントは間違っています。
Shailesh Pratapwar、2018年

45

ポリモーフィズムとは、複数のフォーム、同じオブジェクトが要件に従って異なる操作を実行することを意味します。

ポリモーフィズムは、2つの方法で実現できます。

  1. メソッドのオーバーライド
  2. メソッドのオーバーロード

メソッドのオーバーロードとは、同じクラスに同じメソッド名を使用して2つ以上のメソッドを書き込むことですが、渡すパラメーターが異なります。

メソッドのオーバーライドは、異なるクラスでメソッド名を使用することを意味します。つまり、親クラスのメソッドが子クラスで使用されます。

Javaでは、ポリモーフィズムを実現するために、スーパークラス参照変数がサブクラスオブジェクトを保持できます。

ポリモーフィズムを実現するには、すべての開発者がプロ​​ジェクトで同じメソッド名を使用する必要があります。


4
いい答えは+1。受け入れられた回答は、1つのタイプの多型のみを説明しています。この回答は完了です。
アパダナ2015

1
ポリモーフィズムはパラダイム(OOP)ですが、オーバーライドとオーバーロードは言語機能です。
曾其威

ポリモーフィズムは、ジェネリック型によっても実現できます。
MinhNghĩa19年

43

擬似C#/ Javaでのポリモーフィズムの例を次に示します。

class Animal
{
    abstract string MakeNoise ();
}

class Cat : Animal {
    string MakeNoise () {
        return "Meow";
    }
}

class Dog : Animal {
    string MakeNoise () {
        return "Bark";
    }
}

Main () {
   Animal animal = Zoo.GetAnimal ();
   Console.WriteLine (animal.MakeNoise ());
}

Main関数は動物の種類を認識せず、MakeNoise()メソッドの特定の実装の動作に依存します。

編集:ブライアンは私にパンチを打ったように見えます。おかしい、同じ例を使用しました。しかし、上記のコードは概念を明確にするのに役立ちます。


これは、ランタイムポリモーフィズムの例です。コンパイル時のポリモーフィズムは、メソッドのオーバーロードとジェネリック型によっても可能です。
ピートカーカム、2010

形状->平行四辺形->長方形->正方形
mpen

@ yankee2905この場合、クラスが複数のインターフェースを実装できるため、インターフェースを使用できると思います。
Sam003

1
@Zhishengまたは、抽象親クラスにpeeメソッドを追加しますか?インターフェイスを使用して他のものを実装します。
joey rohan

42

オーバーライドとオーバーロードの両方を使用して、ポリモーフィズムを実現します。

1つ以上のサブクラスでオーバーライドされるクラスにメソッドを含めることができます。このメソッドは、オブジェクトのインスタンス化に使用されたクラスに応じて、さまざまな処理を行います。

    abstract class Beverage {
       boolean isAcceptableTemperature();
    }

    class Coffee extends Beverage {
       boolean isAcceptableTemperature() { 
           return temperature > 70;
       }
    }

    class Wine extends Beverage {
       boolean isAcceptableTemperature() { 
           return temperature < 10;
       }
    }

2つ以上の引数のセットでオーバーロードされるメソッドを使用することもでき ます。このメソッドは、渡された引数のタイプに基づいてさまざまなことを行います。

    class Server {
        public void pour (Coffee liquid) {
            new Cup().fillToTopWith(liquid);
        }

        public void pour (Wine liquid) {
            new WineGlass().fillHalfwayWith(liquid);
        }

        public void pour (Lemonade liquid, boolean ice) {
            Glass glass = new Glass();
            if (ice) {
                glass.fillToTopWith(new Ice());
            }
            glass.fillToTopWith(liquid);
        }
    }

歴史的にメソッドのオーバーロードはオブジェクト指向パラダイムの多態性の一部とは見なされていなかったため、反対票が投じられたと思います。メソッドのオーバーロードとポリモーフィズムは、プログラミング言語の2つの直交する独立した機能です。
セルジオアコスタ

7
ここで私の回答で述べたように、私は同意しません-2つの機能は直交していないが、密接に関連しています。ポリモーフィズム!=継承。あなたは私の賛成票を持っています。
Peter Meyer、

2
言い換えれば、型ポリモーフィズム対アドホックポリモーフィズム。オーバーロードとオーバーライドの両方がポリモーフィズムに関連していると正しく記述されているので、完全ではなくても、この答えを支持しています。OOP言語のポリモーフィズムはクラスの継承によってのみ達成できると言うのは間違っています。JavaやC ++以外にも、複数のディスパッチ、アドホックポリモーフィズム、パラメトリックポリモーフィズムなどの概念を使用できるOOP言語がいくつかあることを思い出してください。 。
rsenna 2014

2
@rsennaこれは不完全かもしれませんが、残りのIMHOよりもはるかによく質問に答えます。また、アドホックでパラメトリックなポリモーフィズムについて言及したことは非常に素晴らしいことです。
Valentin Radu

15

あなたは過負荷が答えではないことは正しいです。

どちらもオーバーライドされていません。オーバーライドは、ポリモーフィズムを取得する手段です。ポリモーフィズムとは、オブジェクトがそのタイプに基づいて動作を変化させる機能です。これは、ポリモーフィズムを示すオブジェクトの呼び出し元がオブジェクトの特定のタイプを認識していない場合に最もよく示されます。


3
変化するのはオブジェクトの動作ではなく、その実装です。同じ動作、異なる実装、それは多態性です。
QBziZ 2008

@QBziZ 動作、特に同じ形容詞を定義する必要があります。動作が同じである場合、それらの実装が異なるのはなぜですか?誰かが特定の実装に不満を抱いているわけではないため、別の実装が必要です。
Sнаđошƒаӽ

11

具体的には、オーバーロードまたはオーバーライドすることで全体像がわかりません。ポリモーフィズムとは、オブジェクトのタイプに基づいてその動作を特殊化する機能です。

同じ名前のメソッドが異なる動作をして異なるパラメーター型を与えることができる場合のオーバーロードは多態性(パラメトリック多態性)の一種であるという点で、私はここでの答えのいくつかに同意しません。良い例は、オペレーターのオーバーロードです。「+」を定義して、さまざまなタイプのパラメーター(文字列やintなど)を受け入れることができます。これらのタイプに基づいて、「+」の動作は異なります。

ポリモーフィズムには、継承およびオーバーライドメソッドも含まれますが、基本タイプでは抽象または仮想にすることができます。継承ベースのポリモーフィズムに関して、Javaは単一クラスの継承のみをサポートし、ポリモーフィックな動作を基本型の単一チェーンの振る舞いに制限します。Javaは、ポリモーフィック動作のさらに別の形式である複数のインターフェースの実装をサポートしています。


関係する単語の一般的な意味はあなたの言うとおりですが、プログラミングの文脈では、人々が「ポリモーフィズム」と言った場合、常に「継承ベースのポリモーフィズム」を意味します。興味深い点ですが、ポリモーフィズムをこのように説明すると、人々を混乱させると思います。
Digital Gabeg 2008

継承だけでポリモーフィズムを説明する方が簡単かもしれませんが、この特定の質問の質問方法では、パラメトリックポリモーフィズムも説明するのが賢明だと思います。
Patrick McElhaney、2008

4
明確にするために、ここではいくつかの回答が絶対的なものとして提示されているため、さまざまな形式を記載する必要があると思います。「プログラマーの文脈での「多態性」は常に「継承ベースの多態性」を意味する」と私は敬意を表しては同意しません
Peter Meyer

2
私が過負荷には、より良い広告-hoc_polymorphismとして分類されると思いますen.wikipedia.org/wiki/...
マヌー

以下の点については、「The Digital Gabeg」に同意する傾向があります。OOPについて説明する場合、多態性は通常、サブタイプの多態性を意味し、型理論について説明する場合は、任意のタイプの多態性を意味します。
Manu

7

ポリモーフィズムとは単に「多くの形式」を意味します。

継承を実現する必要はありません...継承ではないインターフェイスの実装が多態的なニーズに対応するためです。おそらく、インターフェイスの実装は、継承よりも「より良い」多態的なニーズに対応します。

たとえば、飛ぶことができるすべてのものを記述するスーパークラスを作成しますか?私は考えるべきではありません。フライトを説明するインターフェースを作成し、そのままにしておくのが最善です。

したがって、インターフェースは振る舞いを記述し、メソッド名は(プログラマーにとって)振る舞いを記述しているため、メソッドのオーバーロードをポリモーフィズムのより低い形式と見なすことはそれほど難しいことではありません。


2
間違いなく最高の答えです。ポリモーフィズムは、名詞(クラス)でも動詞(メソッド)でも、すべての言語構成に適用できます。
Radu Gasler、2012年

6

典型的な例として、犬と猫は動物であり、動物はmakeNoiseメソッドを持っています。動物のmakeNoiseを呼び出す一連の動物を反復処理し、それぞれの実装を行うことを期待できます。

呼び出しコードは、特定の動物を知る必要はありません。

それは私がポリモーフィズムとして考えるものです。


4

ポリモーフィズムは、オブジェクトが複数の形式で表示される機能です。これには、継承および仮想関数を使用して、交換可能なオブジェクトのファミリーを構築することが含まれます。基本クラスには、仮想関数のプロトタイプが含まれます。アプリケーションの指示に応じて、実装されていないか、デフォルトの実装が含まれている可能性があります。さまざまな派生クラスは、それぞれが異なる動作に影響を与えるように実装します。


4

どちらでもない:

オーバーロードとは、異なるパラメーターをとる同じ関数名がある場合です。

オーバーライドとは、子クラスが親のメソッドを独自のメソッドで置き換えるときです(これ自体は、ポリモーフィズムを構成しません)。

ポリモーフィズムは遅延バインディングです。たとえば、基本クラス(親)メソッドが呼び出されますが、アプリケーションが実際のオブジェクトが何であるかをアプリケーションが認識するまでは、メソッドが異なる子クラスである可能性があります。これは、基本クラスが定義されている場所で任意の子クラスを使用できるためです。

Javaでは、コレクションライブラリでポリモーフィズムがよく見られます。

int countStuff(List stuff) {
  return stuff.size();
}

Listは基本クラスです。リンクされたリスト、ベクトル、配列、またはカスタムリストの実装を数える場合、リストのように機能する限り、コンパイラーは手掛かりがありません。

List myStuff = new MyTotallyAwesomeList();
int result = countStuff(myStuff);

オーバーロードしている場合は、次のようになります。

int countStuff(LinkedList stuff) {...}
int countStuff(ArrayList stuff) {...}
int countStuff(MyTotallyAwesomeList stuff) {...}
etc...

そして、countStuff()の正しいバージョンは、パラメーターと一致するようにコンパイラーによって選択されます。


4

ポリモーフィズムについては、この投稿ですでに詳細に説明されていますが、なぜその一部なのかについてもっと強調したいと思います。

ポリモーフィズムがOOP言語で非常に重要である理由。

継承/ポリモーフィズムの有無にかかわらず、テレビ用のシンプルなアプリケーションを作成してみましょう。アプリケーションの各バージョンを投稿し、小さな回顧を行います。

あなたがテレビ会社のソフトウェアエンジニアであり、ボリューム、明るさ、カラーコントローラーのソフトウェアを記述して、ユーザーコマンドでそれらの値を増減させると仮定します。

追加することにより、これらの各機能のクラスを作成することから始めます。

  1. set:-コントローラの値を設定します(これにコントローラ固有のコードがあるとします)
  2. get:-コントローラの値を取得します(これにコントローラ固有のコードがあるとします)
  3. 調整:-入力を検証し、コントローラーを設定します。(一般的な検証..コントローラーとは無関係)
  4. コントローラーを使用したユーザー入力マッピング:-ユーザー入力を取得し、それに応じてコントローラーを起動します。

アプリケーションバージョン1

import java.util.Scanner;    
class VolumeControllerV1 {
    private int value;
    int get()    {
        return value;
    }
    void set(int value) {
        System.out.println("Old value of VolumeController \t"+this.value);
        this.value = value;
        System.out.println("New value of VolumeController \t"+this.value);
    }
    void adjust(int value)  {
        int temp = this.get();
        if(((value > 0) && (temp >= 100)) || ((value < 0) && (temp <= 0)))    {
            System.out.println("Can not adjust any further");
            return;
        }
        this.set(temp + value);
    }
}
class  BrightnessControllerV1 {
    private int value;
    int get()    {
        return value;
    }
    void set(int value) {
        System.out.println("Old value of BrightnessController \t"+this.value);
        this.value = value;
        System.out.println("New value of BrightnessController \t"+this.value);
    }
    void adjust(int value)  {
        int temp = this.get();
        if(((value > 0) && (temp >= 100)) || ((value < 0) && (temp <= 0)))    {
            System.out.println("Can not adjust any further");
            return;
        }
        this.set(temp + value);
    }
}
class ColourControllerV1    {
    private int value;
    int get()    {
        return value;
    }
    void set(int value) {
        System.out.println("Old value of ColourController \t"+this.value);
        this.value = value;
        System.out.println("New value of ColourController \t"+this.value);
    }
    void adjust(int value)  {
        int temp = this.get();
        if(((value > 0) && (temp >= 100)) || ((value < 0) && (temp <= 0)))    {
            System.out.println("Can not adjust any further");
            return;
        }
        this.set(temp + value);
    }
}

/*
 *       There can be n number of controllers
 * */
public class TvApplicationV1 {
    public static void main(String[] args)  {
        VolumeControllerV1 volumeControllerV1 = new VolumeControllerV1();
        BrightnessControllerV1 brightnessControllerV1 = new BrightnessControllerV1();
        ColourControllerV1 colourControllerV1 = new ColourControllerV1();


        OUTER: while(true) {
            Scanner sc=new Scanner(System.in);
            System.out.println(" Enter your option \n Press 1 to increase volume \n Press 2 to decrease volume");
            System.out.println(" Press 3 to increase brightness \n Press 4 to decrease brightness");
            System.out.println(" Press 5 to increase color \n Press 6 to decrease color");
            System.out.println("Press any other Button to shutdown");
            int button = sc.nextInt();
            switch (button) {
                case  1:    {
                    volumeControllerV1.adjust(5);
                    break;
                }
                case 2: {
                    volumeControllerV1.adjust(-5);
                    break;
                }
                case  3:    {
                    brightnessControllerV1.adjust(5);
                    break;
                }
                case 4: {
                    brightnessControllerV1.adjust(-5);
                    break;
                }
                case  5:    {
                    colourControllerV1.adjust(5);
                    break;
                }
                case 6: {
                colourControllerV1.adjust(-5);
                break;
            }
            default:
                System.out.println("Shutting down...........");
                break OUTER;
        }

    }
    }
}

これで、デプロイする準備ができた作業用アプリケーションの最初のバージョンができました。これまでに行われた作業を分析する時間。

TVアプリケーションバージョン1の問題

  1. Adjust(int value)コードは3つのクラスすべてで重複しています。コードの重複を最小限に抑えたい。(しかし、一般的なコードについて考えず、コードの重複を避けるためにスーパークラスに移動しました)

アプリケーションが期待どおりに動作する限り、それを維持することにします。

時々、上司が戻ってきて、既存のアプリケーションにリセット機能を追加するように求めてきます。リセットすると、3つすべての3つのコントローラーがそれぞれのデフォルト値に設定されます。

新しい機能の新しいクラス(ResetFunctionV2)の作成を開始し、この新しい機能のユーザー入力マッピングコードをマップします。

アプリケーションバージョン2

import java.util.Scanner;
class VolumeControllerV2    {

    private int defaultValue = 25;
    private int value;

    int getDefaultValue() {
        return defaultValue;
    }
    int get()    {
        return value;
    }
    void set(int value) {
        System.out.println("Old value of VolumeController \t"+this.value);
        this.value = value;
        System.out.println("New value of VolumeController \t"+this.value);
    }
    void adjust(int value)  {
        int temp = this.get();
        if(((value > 0) && (temp >= 100)) || ((value < 0) && (temp <= 0)))    {
            System.out.println("Can not adjust any further");
            return;
        }
        this.set(temp + value);
    }
}
class  BrightnessControllerV2   {

    private int defaultValue = 50;
    private int value;
    int get()    {
        return value;
    }
    int getDefaultValue() {
        return defaultValue;
    }
    void set(int value) {
        System.out.println("Old value of BrightnessController \t"+this.value);
        this.value = value;
        System.out.println("New value of BrightnessController \t"+this.value);
    }
    void adjust(int value)  {
        int temp = this.get();
        if(((value > 0) && (temp >= 100)) || ((value < 0) && (temp <= 0)))    {
            System.out.println("Can not adjust any further");
            return;
        }
        this.set(temp + value);
    }
}
class ColourControllerV2    {

    private int defaultValue = 40;
    private int value;
    int get()    {
        return value;
    }
    int getDefaultValue() {
        return defaultValue;
    }
    void set(int value) {
        System.out.println("Old value of ColourController \t"+this.value);
        this.value = value;
        System.out.println("New value of ColourController \t"+this.value);
    }
    void adjust(int value)  {
        int temp = this.get();
        if(((value > 0) && (temp >= 100)) || ((value < 0) && (temp <= 0)))    {
            System.out.println("Can not adjust any further");
            return;
        }
        this.set(temp + value);
    }
}

class ResetFunctionV2 {

    private VolumeControllerV2 volumeControllerV2 ;
    private BrightnessControllerV2 brightnessControllerV2;
    private ColourControllerV2 colourControllerV2;

    ResetFunctionV2(VolumeControllerV2 volumeControllerV2, BrightnessControllerV2 brightnessControllerV2, ColourControllerV2 colourControllerV2)  {
        this.volumeControllerV2 = volumeControllerV2;
        this.brightnessControllerV2 = brightnessControllerV2;
        this.colourControllerV2 = colourControllerV2;
    }
    void onReset()    {
        volumeControllerV2.set(volumeControllerV2.getDefaultValue());
        brightnessControllerV2.set(brightnessControllerV2.getDefaultValue());
        colourControllerV2.set(colourControllerV2.getDefaultValue());
    }
}
/*
 *       so on
 *       There can be n number of controllers
 *
 * */
public class TvApplicationV2 {
    public static void main(String[] args)  {
        VolumeControllerV2 volumeControllerV2 = new VolumeControllerV2();
        BrightnessControllerV2 brightnessControllerV2 = new BrightnessControllerV2();
        ColourControllerV2 colourControllerV2 = new ColourControllerV2();

        ResetFunctionV2 resetFunctionV2 = new ResetFunctionV2(volumeControllerV2, brightnessControllerV2, colourControllerV2);

        OUTER: while(true) {
            Scanner sc=new Scanner(System.in);
            System.out.println(" Enter your option \n Press 1 to increase volume \n Press 2 to decrease volume");
            System.out.println(" Press 3 to increase brightness \n Press 4 to decrease brightness");
            System.out.println(" Press 5 to increase color \n Press 6 to decrease color");
            System.out.println(" Press 7 to reset TV \n Press any other Button to shutdown");
            int button = sc.nextInt();
            switch (button) {
                case  1:    {
                    volumeControllerV2.adjust(5);
                    break;
                }
                case 2: {
                    volumeControllerV2.adjust(-5);
                    break;
                }
                case  3:    {
                    brightnessControllerV2.adjust(5);
                    break;
                }
                case 4: {
                    brightnessControllerV2.adjust(-5);
                    break;
                }
                case  5:    {
                    colourControllerV2.adjust(5);
                    break;
                }
                case 6: {
                    colourControllerV2.adjust(-5);
                    break;
                }
                case 7: {
                    resetFunctionV2.onReset();
                    break;
                }
                default:
                    System.out.println("Shutting down...........");
                    break OUTER;
            }

        }
    }
}

したがって、リセット機能を使用してアプリケーションを準備できます。しかし、今あなたはそれを実現し始めます

TVアプリケーションバージョン2の問題

  1. 新しいコントローラーが製品に導入された場合、リセット機能コードを変更する必要があります。
  2. コントローラの数が非常に多くなると、コントローラの参照の保持に問題が発生します。
  3. リセット機能コードは、すべてのコントローラークラスのコード(デフォルト値を取得および設定するため)と密に結合されています。
  4. リセット機能クラス(ResetFunctionV2)は、コントローラークラス(調整)の他のメソッドにアクセスできますが、これは望ましくありません。

同時に、起動時に各コントローラーが会社のホストされているドライバーリポジトリからインターネット経由で最新バージョンのドライバーをチェックする必要がある機能を追加する必要がある可能性があることをボスから聞いています。

ここで、追加するこの新しい機能はリセット機能に似ていると考え始め、アプリケーションをリファクタリングしない場合、アプリケーションの問題(V2)が増加します。

JAVAのポリモーフィック機能を利用できるように継承の使用を考え始め、新しい抽象クラス(ControllerV3)を追加します。

  1. getおよびsetメソッドのシグネチャを宣言します。
  2. 以前にすべてのコントローラー間で複製された調整メソッド実装が含まれています。
  3. ポリモーフィズムを利用してリセット機能を簡単に実装できるように、setDefaultメソッドを宣言します。

これらの改善により、TVアプリケーションのバージョン3が用意されました。

アプリケーションバージョン3

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

abstract class ControllerV3 {
    abstract void set(int value);
    abstract int get();
    void adjust(int value)  {
        int temp = this.get();
        if(((value > 0) && (temp >= 100)) || ((value < 0) && (temp <= 0)))    {
            System.out.println("Can not adjust any further");
            return;
        }
        this.set(temp + value);
    }
    abstract void setDefault();
}
class VolumeControllerV3 extends ControllerV3   {

    private int defaultValue = 25;
    private int value;

    public void setDefault() {
        set(defaultValue);
    }
    int get()    {
        return value;
    }
    void set(int value) {
        System.out.println("Old value of VolumeController \t"+this.value);
        this.value = value;
        System.out.println("New value of VolumeController \t"+this.value);
    }
}
class  BrightnessControllerV3  extends ControllerV3   {

    private int defaultValue = 50;
    private int value;

    public void setDefault() {
        set(defaultValue);
    }
    int get()    {
        return value;
    }
    void set(int value) {
        System.out.println("Old value of BrightnessController \t"+this.value);
        this.value = value;
        System.out.println("New value of BrightnessController \t"+this.value);
    }
}
class ColourControllerV3 extends ControllerV3   {

    private int defaultValue = 40;
    private int value;

    public void setDefault() {
        set(defaultValue);
    }
    int get()    {
        return value;
    }
    void set(int value) {
        System.out.println("Old value of ColourController \t"+this.value);
        this.value = value;
        System.out.println("New value of ColourController \t"+this.value);
    }
}

class ResetFunctionV3 {

    private List<ControllerV3> controllers = null;

    ResetFunctionV3(List<ControllerV3> controllers)  {
        this.controllers = controllers;
    }
    void onReset()    {
        for (ControllerV3 controllerV3 :this.controllers)  {
            controllerV3.setDefault();
        }
    }
}
/*
 *       so on
 *       There can be n number of controllers
 *
 * */
public class TvApplicationV3 {
    public static void main(String[] args)  {
        VolumeControllerV3 volumeControllerV3 = new VolumeControllerV3();
        BrightnessControllerV3 brightnessControllerV3 = new BrightnessControllerV3();
        ColourControllerV3 colourControllerV3 = new ColourControllerV3();

        List<ControllerV3> controllerV3s = new ArrayList<>();
        controllerV3s.add(volumeControllerV3);
        controllerV3s.add(brightnessControllerV3);
        controllerV3s.add(colourControllerV3);

        ResetFunctionV3 resetFunctionV3 = new ResetFunctionV3(controllerV3s);

        OUTER: while(true) {
            Scanner sc=new Scanner(System.in);
            System.out.println(" Enter your option \n Press 1 to increase volume \n Press 2 to decrease volume");
            System.out.println(" Press 3 to increase brightness \n Press 4 to decrease brightness");
            System.out.println(" Press 5 to increase color \n Press 6 to decrease color");
            System.out.println(" Press 7 to reset TV \n Press any other Button to shutdown");
            int button = sc.nextInt();
            switch (button) {
                case  1:    {
                    volumeControllerV3.adjust(5);
                    break;
                }
                case 2: {
                    volumeControllerV3.adjust(-5);
                    break;
                }
                case  3:    {
                    brightnessControllerV3.adjust(5);
                    break;
                }
                case 4: {
                    brightnessControllerV3.adjust(-5);
                    break;
                }
                case  5:    {
                    colourControllerV3.adjust(5);
                    break;
                }
                case 6: {
                    colourControllerV3.adjust(-5);
                    break;
                }
                case 7: {
                    resetFunctionV3.onReset();
                    break;
                }
                default:
                    System.out.println("Shutting down...........");
                    break OUTER;
            }

        }
    }
}

V2の問題リストにリストされている問題のほとんどは、

TVアプリケーションバージョン3の問題

  1. リセット機能クラス(ResetFunctionV3)は、コントローラークラス(調整)の他のメソッドにアクセスできますが、これは望ましくありません。

繰り返しますが、この問題を解決することを考えます。これで、実装する別の機能(起動時のドライバーの更新)も用意できました。修正しないと、新しい機能にも複製されます。

したがって、抽象クラスで定義されたコントラクトを分割し、2つのインターフェイスを記述します。

  1. リセット機能。
  2. ドライバーの更新。

そしてあなたの最初の具象クラスに以下のようにそれらを実装させます

アプリケーションバージョン4

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

interface OnReset {
    void setDefault();
}
interface OnStart {
    void checkForDriverUpdate();
}
abstract class ControllerV4 implements OnReset,OnStart {
    abstract void set(int value);
    abstract int get();
    void adjust(int value)  {
        int temp = this.get();
        if(((value > 0) && (temp >= 100)) || ((value < 0) && (temp <= 0)))    {
            System.out.println("Can not adjust any further");
            return;
        }
        this.set(temp + value);
    }
}

class VolumeControllerV4 extends ControllerV4 {

    private int defaultValue = 25;
    private int value;
    @Override
    int get()    {
        return value;
    }
    void set(int value) {
        System.out.println("Old value of VolumeController \t"+this.value);
        this.value = value;
        System.out.println("New value of VolumeController \t"+this.value);
    }
    @Override
    public void setDefault() {
        set(defaultValue);
    }

    @Override
    public void checkForDriverUpdate()    {
        System.out.println("Checking driver update for VolumeController .... Done");
    }
}
class  BrightnessControllerV4 extends ControllerV4 {

    private int defaultValue = 50;
    private int value;
    @Override
    int get()    {
        return value;
    }
    @Override
    void set(int value) {
        System.out.println("Old value of BrightnessController \t"+this.value);
        this.value = value;
        System.out.println("New value of BrightnessController \t"+this.value);
    }

    @Override
    public void setDefault() {
        set(defaultValue);
    }

    @Override
    public void checkForDriverUpdate()    {
        System.out.println("Checking driver update for BrightnessController .... Done");
    }
}
class ColourControllerV4 extends ControllerV4 {

    private int defaultValue = 40;
    private int value;
    @Override
    int get()    {
        return value;
    }
    void set(int value) {
        System.out.println("Old value of ColourController \t"+this.value);
        this.value = value;
        System.out.println("New value of ColourController \t"+this.value);
    }
    @Override
    public void setDefault() {
        set(defaultValue);
    }

    @Override
    public void checkForDriverUpdate()    {
        System.out.println("Checking driver update for ColourController .... Done");
    }
}
class ResetFunctionV4 {

    private List<OnReset> controllers = null;

    ResetFunctionV4(List<OnReset> controllers)  {
        this.controllers = controllers;
    }
    void onReset()    {
        for (OnReset onreset :this.controllers)  {
            onreset.setDefault();
        }
    }
}
class InitializeDeviceV4 {

    private List<OnStart> controllers = null;

    InitializeDeviceV4(List<OnStart> controllers)  {
        this.controllers = controllers;
    }
    void initialize()    {
        for (OnStart onStart :this.controllers)  {
            onStart.checkForDriverUpdate();
        }
    }
}
/*
*       so on
*       There can be n number of controllers
*
* */
public class TvApplicationV4 {
    public static void main(String[] args)  {
        VolumeControllerV4 volumeControllerV4 = new VolumeControllerV4();
        BrightnessControllerV4 brightnessControllerV4 = new BrightnessControllerV4();
        ColourControllerV4 colourControllerV4 = new ColourControllerV4();
        List<ControllerV4> controllerV4s = new ArrayList<>();
        controllerV4s.add(brightnessControllerV4);
        controllerV4s.add(volumeControllerV4);
        controllerV4s.add(colourControllerV4);

        List<OnStart> controllersToInitialize = new ArrayList<>();
        controllersToInitialize.addAll(controllerV4s);
        InitializeDeviceV4 initializeDeviceV4 = new InitializeDeviceV4(controllersToInitialize);
        initializeDeviceV4.initialize();

        List<OnReset> controllersToReset = new ArrayList<>();
        controllersToReset.addAll(controllerV4s);
        ResetFunctionV4 resetFunctionV4 = new ResetFunctionV4(controllersToReset);

        OUTER: while(true) {
            Scanner sc=new Scanner(System.in);
            System.out.println(" Enter your option \n Press 1 to increase volume \n Press 2 to decrease volume");
            System.out.println(" Press 3 to increase brightness \n Press 4 to decrease brightness");
            System.out.println(" Press 5 to increase color \n Press 6 to decrease color");
            System.out.println(" Press 7 to reset TV \n Press any other Button to shutdown");
            int button = sc.nextInt();
            switch (button) {
                case  1:    {
                    volumeControllerV4.adjust(5);
                    break;
                }
                case 2: {
                    volumeControllerV4.adjust(-5);
                    break;
                }
                case  3:    {
                    brightnessControllerV4.adjust(5);
                    break;
                }
                case 4: {
                    brightnessControllerV4.adjust(-5);
                    break;
                }
                case  5:    {
                    colourControllerV4.adjust(5);
                    break;
                }
                case 6: {
                    colourControllerV4.adjust(-5);
                    break;
                }
                case 7: {
                    resetFunctionV4.onReset();
                    break;
                }
                default:
                    System.out.println("Shutting down...........");
                    break OUTER;
            }

        }
    }
}

これで、あなたが直面しているすべての問題が解決され、継承とポリモーフィズムを使用することで、

  1. アプリケーションのさまざまな部分を疎結合にします(リセットまたはドライバー更新機能のコンポーネントは、実際のコントローラークラス(ボリューム、明るさ、色)を認識する必要はありません。OnResetまたはOnStartを実装するクラスは、リセットまたはドライバー更新機能に受け入れられます。コンポーネント)。
  2. アプリケーションの機能強化が容易になります(コントローラーを新しく追加しても、リセットやドライバーの更新機能のコンポーネントには影響がなく、新しいものを追加するのが非常に簡単になりました)。
  3. 抽象化のレイヤーを保持します(現在、リセット機能はコントローラーのsetDefaultメソッドのみを表示でき、リセット機能はコントローラーのcheckForDriverUpdateメソッドのみを表示できます)。

お役に立てれば :-)


3

オーバーロードという用語は、同じ名前の何かの複数のバージョンを持つことを指します。通常は、パラメーターリストが異なるメソッドです。

public int DoSomething(int objectId) { ... }
public int DoSomething(string objectName) { ... }

したがって、これらの関数は同じことを行う可能性がありますが、IDまたは名前で呼び出すことができます。継承、抽象クラスなどとは関係ありません。

オーバーライドは通常、質問で説明したように、ポリモーフィズムを指します


2

オーバーロードとは、同じ名前でパラメータが異なる2つのメソッドを定義する場合

オーバーライドとは、サブクラス内の同じ名前の関数を介して基本クラスの動作を変更することです。

したがって、ポリモーフィズムはオーバーライドに関連していますが、実際にはオーバーロードされていません。

しかし、誰かが「ポリモーフィズムとは何ですか?」という質問に対して「オーバーライドする」という簡単な答えをくれた場合 さらに説明をお願いします。


2

オーバーライドは、上位レベルのメソッド(スーパーメソッド)と同じ名前とシグネチャを持つメソッドを宣言することにより、継承されたメソッドを非表示にすることに似ています。これにより、クラスにポリモーフィックな動作が追加されます。つまり、呼び出されるレベルのメソッドを選択する決定は、コンパイル時ではなく実行時に行われます。これは、インターフェースと実装の概念につながります。


2

ポリモーフィズムとは何ですか?

Java チュートリアルから

多型の辞書定義は、生物または種が多くの異なる形態または段階を持つことができる生物学の原理を指します。この原則は、オブジェクト指向プログラミングやJava言語などの言語にも適用できます。クラスのサブクラスは、独自の動作を定義しながら、親クラスと同じ機能の一部を共有できます。

例と定義を検討することにより、オーバーライドは受け入れられた答えになります。

2番目のクエリについて:

実装のないメソッドを定義した抽象基本クラスがあり、そのメソッドをサブクラスで定義した場合でも、それはオーバーライドされますか?

オーバーライドと呼ばれるべきです。

さまざまなタイプのオーバーライドを理解するには、この例をご覧ください。

  1. 基本クラスは実装を提供せず、サブクラスは完全なメソッドをオーバーライドする必要があります-(抽象)
  2. 基本クラスはデフォルトの実装を提供し、サブクラスは動作を変更できます
  3. サブクラスは、呼び出しによって基本クラス実装に拡張機能を追加します super.methodName()、最初のステートメントとして
  4. 基本クラスはアルゴリズム(テンプレートメソッド)の構造を定義し、サブクラスはアルゴリズムの一部をオーバーライドします

コードスニペット:

import java.util.HashMap;

abstract class Game implements Runnable{

    protected boolean runGame = true;
    protected Player player1 = null;
    protected Player player2 = null;
    protected Player currentPlayer = null;

    public Game(){
        player1 = new Player("Player 1");
        player2 = new Player("Player 2");
        currentPlayer = player1;
        initializeGame();
    }

    /* Type 1: Let subclass define own implementation. Base class defines abstract method to force
        sub-classes to define implementation    
    */

    protected abstract void initializeGame();

    /* Type 2: Sub-class can change the behaviour. If not, base class behaviour is applicable */
    protected void logTimeBetweenMoves(Player player){
        System.out.println("Base class: Move Duration: player.PlayerActTime - player.MoveShownTime");
    }

    /* Type 3: Base class provides implementation. Sub-class can enhance base class implementation by calling
        super.methodName() in first line of the child class method and specific implementation later */
    protected void logGameStatistics(){
        System.out.println("Base class: logGameStatistics:");
    }
    /* Type 4: Template method: Structure of base class can't be changed but sub-class can some part of behaviour */
    protected void runGame() throws Exception{
        System.out.println("Base class: Defining the flow for Game:");  
        while ( runGame) {
            /*
            1. Set current player
            2. Get Player Move
            */
            validatePlayerMove(currentPlayer);  
            logTimeBetweenMoves(currentPlayer);
            Thread.sleep(500);
            setNextPlayer();
        }
        logGameStatistics();
    }
    /* sub-part of the template method, which define child class behaviour */
    protected abstract void validatePlayerMove(Player p);

    protected void setRunGame(boolean status){
        this.runGame = status;
    }
    public void setCurrentPlayer(Player p){
        this.currentPlayer = p;
    }
    public void setNextPlayer(){
        if ( currentPlayer == player1) {
            currentPlayer = player2;
        }else{
            currentPlayer = player1;
        }
    }
    public void run(){
        try{
            runGame();
        }catch(Exception err){
            err.printStackTrace();
        }
    }
}

class Player{
    String name;
    Player(String name){
        this.name = name;
    }
    public String getName(){
        return name;
    }
}

/* Concrete Game implementation  */
class Chess extends Game{
    public Chess(){
        super();
    }
    public void initializeGame(){
        System.out.println("Child class: Initialized Chess game");
    }
    protected void validatePlayerMove(Player p){
        System.out.println("Child class: Validate Chess move:"+p.getName());
    }
    protected void logGameStatistics(){
        super.logGameStatistics();
        System.out.println("Child class: Add Chess specific logGameStatistics:");
    }
}
class TicTacToe extends Game{
    public TicTacToe(){
        super();
    }
    public void initializeGame(){
        System.out.println("Child class: Initialized TicTacToe game");
    }
    protected void validatePlayerMove(Player p){
        System.out.println("Child class: Validate TicTacToe move:"+p.getName());
    }
}

public class Polymorphism{
    public static void main(String args[]){
        try{

            Game game = new Chess();
            Thread t1 = new Thread(game);
            t1.start();
            Thread.sleep(1000);
            game.setRunGame(false);
            Thread.sleep(1000);

            game = new TicTacToe();
            Thread t2 = new Thread(game);
            t2.start();
            Thread.sleep(1000);
            game.setRunGame(false);

        }catch(Exception err){
            err.printStackTrace();
        }       
    }
}

出力:

Child class: Initialized Chess game
Base class: Defining the flow for Game:
Child class: Validate Chess move:Player 1
Base class: Move Duration: player.PlayerActTime - player.MoveShownTime
Child class: Validate Chess move:Player 2
Base class: Move Duration: player.PlayerActTime - player.MoveShownTime
Base class: logGameStatistics:
Child class: Add Chess specific logGameStatistics:
Child class: Initialized TicTacToe game
Base class: Defining the flow for Game:
Child class: Validate TicTacToe move:Player 1
Base class: Move Duration: player.PlayerActTime - player.MoveShownTime
Child class: Validate TicTacToe move:Player 2
Base class: Move Duration: player.PlayerActTime - player.MoveShownTime
Base class: logGameStatistics:

2

皆さんはあなたがコンセプトを混合していると思います。ポリモーフィズムとは、オブジェクトが実行時に異なる動作をする能力です。これを実現するには、次の2つの要件が必要です。

  1. レイトバインディング
  2. 継承。

とは言っても、オーバーロードは、使用している言語によってはオーバーライドとは異なること意味します。たとえば、Javaにはオーバーライドではなく、オーバーロードが存在します。基本クラスとは異なるシグニチャーを持つオーバーロードされたメソッドは、サブクラスで使用できます。そうでない場合、それらはオーバーライドされます(オブジェクトの外部から基本クラスのメソッドを呼び出す方法がないということを意味します)。

ただし、C ++ではそうではありません。任意のオーバーロードされたメソッドは、独立して、署名が(diffrrent量、異なるタイプ)が同じであるか否かだけでなくとしてある上書き。つまり、現在、基本クラスのメソッドは、サブクラスオブジェクトの外部から呼び出されたときに、サブクラスで使用できなくなります。

したがって、答えは、Javaの使用のオーバーロードについて話すときです。他の言語ではc ++で発生するため、異なる場合があります


1

ポリモーフィズムは、その意味に関する限り、JavaでOVERRIDING する可能性が高くなります

それはすべて、さまざまな状況でのSAMEオブジェクトのさまざまな動作に関するものです(プログラミングの方法では、さまざまな引数を呼び出すことができます)。

以下の例は理解するのに役立つと思います...それは純粋なJavaコードではありませんが...

     public void See(Friend)
     {
        System.out.println("Talk");
     }

しかし、引数を変更すると...動作が変更されます...

     public void See(Enemy)
     {
        System.out.println("Run");
     }

Person(ここでは「オブジェクト」)は同じです...


1

ポリモーフィズムは、オブジェクトの複数の実装であるか、オブジェクトの複数の形式と言えます。Animals抽象基本クラスとしてクラスがありmovement()、動物が動く方法を定義すると呼ばれるメソッドがあるとします。現在、実際にはさまざまな種類の動物がいます。動物の動きも異なります。2本足の動物もあれば、4本足の動物もあれば、足のないmovement()動物もいます。ただし、クラスDogs Cats Fishなど、より多くのクラスを定義する必要があります。次に、これらのクラスを基本クラスから拡張し、Animalsそのメソッドをオーバーライドする必要がありますmovement()し、を、各動物に基づく新しい移動機能で必要があります。あなたも使うことができますInterfacesそれを達成するために。ここのキーワードはオーバーライドされ、オーバーロードは異なり、ポリモーフィズムとは見なされません。オーバーロードを使用すると、「同じ名前」で複数のメソッドを定義できますが、同じオブジェクトまたはクラスに異なるパラメーターを使用できます。


0

ポリモーフィズムは、単一のインターフェースを使用することにより、異なるオブジェクトを均一に処理させる言語の能力に関連しています。そのため、オーバーライドに関連しているため、インターフェース(または基本クラス)はポリモーフィックであり、実装者はオーバーライドするオブジェクト(同じメダルの2つの面)です。

とにかく、2つの用語の違いは、c ++などの他の言語を使用してより適切に説明されます。c++のポリモーフィックオブジェクトは、ベース関数が仮想の場合、Javaの対応オブジェクトとして動作しますが、メソッドが仮想でない場合、コードジャンプは静的に解決されます。真の型は実行時にチェックされないため、ポリモーフィズムには、オブジェクトへのアクセスに使用されるインターフェイスに応じて異なる動作をする機能が含まれます。擬似コードの例を作ってみましょう:

class animal {
    public void makeRumor(){
        print("thump");
    }
}
class dog extends animal {
    public void makeRumor(){
        print("woff");
    }
}

animal a = new dog();
dog b = new dog();

a.makeRumor() -> prints thump
b.makeRumor() -> prints woff

(makeRumorが仮想ではないと仮定)

javaは、このレベルのポリモーフィズム(オブジェクトスライスとも呼ばれます)を提供していません。

動物a = new dog(); 犬b =新しい犬();

a.makeRumor() -> prints thump
b.makeRumor() -> prints woff

どちらの場合も、woffのみが出力されます。aとbはクラスdogを参照しているため



動物a = new dog(); aは犬として作成され、「woff」を出力します。どきどきさせたい場合は、アップキャストする必要があります。((animal)a).makeRumor()
Chris Cudmore

それは参照アップキャストですが、オブジェクトはまだ犬です。動物にしたい場合は、オブジェクトを明示的にアップキャストする必要があります。
Chris Cudmore

理解した。質問にJavaのタグが付けられました。あなたはC ++に答えました。あなたはC ++で正しいかもしれません。私は間違いなくJavaで正しいです。
Chris Cudmore

コピーコンストラクターが関係するたびに発生するはず です。ここに参照fredosaurus.com/notes-cpp/oop-condestructors/…ケース3の一致があります。作成を明確にするためだけにある新しい演算子は無視してください。
Lorenzo Boccaccia

0
import java.io.IOException;

class Super {

    protected Super getClassName(Super s) throws IOException {
        System.out.println(this.getClass().getSimpleName() + " - I'm parent");
        return null;
    }

}

class SubOne extends Super {

    @Override
    protected Super getClassName(Super s)  {
        System.out.println(this.getClass().getSimpleName() + " - I'm Perfect Overriding");
        return null;
    }

}

class SubTwo extends Super {

    @Override
    protected Super getClassName(Super s) throws NullPointerException {
        System.out.println(this.getClass().getSimpleName() + " - I'm Overriding and Throwing Runtime Exception");
        return null;
    }

}

class SubThree extends Super {

    @Override
    protected SubThree getClassName(Super s) {
        System.out.println(this.getClass().getSimpleName()+ " - I'm Overriding and Returning SubClass Type");
        return null;
    }

}

class SubFour extends Super {

    @Override
    protected Super getClassName(Super s) throws IOException {
        System.out.println(this.getClass().getSimpleName()+ " - I'm Overriding and Throwing Narrower Exception ");
        return null;
    }

}

class SubFive extends Super {

    @Override
    public Super getClassName(Super s) {
        System.out.println(this.getClass().getSimpleName()+ " - I'm Overriding and have broader Access ");
        return null;
    }

}

class SubSix extends Super {

    public Super getClassName(Super s, String ol) {
        System.out.println(this.getClass().getSimpleName()+ " - I'm Perfect Overloading ");
        return null;
    }

}

class SubSeven extends Super {

    public Super getClassName(SubSeven s) {
        System.out.println(this.getClass().getSimpleName()+ " - I'm Perfect Overloading because Method signature (Argument) changed.");
        return null;
    }

}

public class Test{

    public static void main(String[] args) throws Exception {

        System.out.println("Overriding\n");

        Super s1 = new SubOne(); s1.getClassName(null);

        Super s2 = new SubTwo(); s2.getClassName(null);

        Super s3 = new SubThree(); s3.getClassName(null);

        Super s4 = new SubFour(); s4.getClassName(null);

        Super s5 = new SubFive(); s5.getClassName(null);

        System.out.println("Overloading\n");

        SubSix s6 = new SubSix(); s6.getClassName(null, null);

        s6 = new SubSix(); s6.getClassName(null);

        SubSeven s7 = new SubSeven(); s7.getClassName(s7);

        s7 = new SubSeven(); s7.getClassName(new Super());

    }
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.