it-swarm.com.de

Polymorphismus vs Overriding vs Überladung

In Bezug auf Java, wenn jemand fragt:

was ist Polymorphismus?

Wäre Überlastung oder Übersteuerung eine akzeptable Antwort?

Ich denke, es steckt noch ein bisschen mehr dahinter.

Wenn Sie eine abstrakte Basisklasse hatten, die eine Methode ohne Implementierung definiert hat, und Sie diese Methode in der Unterklasse definiert haben, ist das immer noch ein Überschreiben?

Ich denke Überlastung ist nicht die richtige Antwort für Sie.

332
Brian G

Der klarste Weg, Polymorphismus auszudrücken, ist über eine abstrakte Basisklasse (oder Schnittstelle).

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

Diese Klasse ist abstrakt, da die Methode goPee() für Menschen nicht definierbar ist. Es ist nur für die Unterklassen Männlich und Weiblich definierbar. Außerdem ist der Mensch ein abstraktes Konzept - Sie können keinen Menschen erschaffen, der weder männlich noch weiblich ist. Es muss der eine oder andere sein.

Daher verschieben wir die Implementierung mithilfe der abstrakten Klasse.

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

und

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

Jetzt können wir einem ganzen Raum voller Menschen sagen, dass sie pinkeln sollen.

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();
}

Wenn Sie dies ausführen, erhalten Sie:

Stand Up
Sit Down
...
875
Chris Cudmore

Polymorphismus ist die Fähigkeit einer Klasseninstanz, sich so zu verhalten, als wäre sie eine Instanz einer anderen Klasse in ihrem Vererbungsbaum, meistens einer ihrer Vorfahrklassen. Beispielsweise können Sie in Java alle Klassen von Object erben. Daher können Sie eine Variable vom Typ Object erstellen und ihr eine Instanz einer beliebigen Klasse zuweisen.

Ein Überschreiben ist ein Funktionstyp, der in einer Klasse auftritt, die von einer anderen Klasse erbt. Eine Überschreibungsfunktion "ersetzt" eine von der Basisklasse geerbte Funktion, jedoch so, dass sie aufgerufen wird, selbst wenn eine Instanz ihrer Klasse durch Polymorphismus vorgibt, ein anderer Typ zu sein. Im vorherigen Beispiel können Sie Ihre eigene Klasse definieren und die Funktion toString () überschreiben. Da diese Funktion von Object geerbt wird, ist sie weiterhin verfügbar, wenn Sie eine Instanz dieser Klasse in eine Variable vom Typ Object kopieren. Wenn Sie in Ihrer Klasse toString () aufrufen, während sie vorgibt, ein Objekt zu sein, wird normalerweise die Version von toString ausgelöst, die für Object selbst definiert ist. Da es sich bei der Funktion jedoch um eine Überschreibung handelt, wird die Definition von toString () aus Ihrer Klasse verwendet, auch wenn der wahre Typ der Klasseninstanz hinter Polymorphismus verborgen ist.

Überladen ist die Aktion, bei der mehrere Methoden mit demselben Namen, jedoch mit unterschiedlichen Parametern definiert werden. Es hat weder mit Überschreiben noch mit Polymorphismus zu tun.

92

Hier ist ein Beispiel für Polymorphismus in Pseudo-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 ());
}

Die Main-Funktion kennt den Typ des Tieres nicht und hängt vom Verhalten der MakeNoise () -Methode einer bestimmten Implementierung ab.

Bearbeiten: Sieht aus wie Brian mich zu schlagen. Komischerweise haben wir das gleiche Beispiel verwendet. Der obige Code soll jedoch helfen, die Konzepte zu verdeutlichen.

43

Polymorphismus bedeutet mehr als eine Form, dasselbe Objekt, das je nach Anforderung unterschiedliche Operationen ausführt.

Polymorphismus kann auf zwei Arten erreicht werden:

  1. Methode überschreiben
  2. Methodenüberladung

Methodenüberladung bedeutet, dass zwei oder mehr Methoden in derselben Klasse mit demselben Methodennamen geschrieben werden, die Übergabeparameter jedoch unterschiedlich sind.

Überschreiben von Methoden bedeutet, dass wir die Methodennamen in den verschiedenen Klassen verwenden, dh, dass in der untergeordneten Klasse die Methode der übergeordneten Klasse verwendet wird.

In Java um Polymorphismus zu erreichen, kann eine Superklasse-Referenzvariable das Unterklassenobjekt enthalten.

Um den Polymorphismus zu erreichen, muss jeder Entwickler im Projekt dieselben Methodennamen verwenden.

43
manoj

Sowohl das Überschreiben als auch das Überladen werden verwendet, um einen Polymorphismus zu erzielen.

Sie könnten eine Methode in einer Klasse haben, die überschrieben in einer oder mehreren Unterklassen ist. Die Methode führt je nach Klasse, mit der ein Objekt instanziiert wurde, unterschiedliche Aktionen aus.

    abstract class Beverage {
       boolean isAcceptableTemperature();
    }

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

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

Sie könnten auch eine Methode haben, die überladen mit zwei oder mehr Gruppen von Argumenten ist. Die Methode führt basierend auf den übergebenen Argumenttypen verschiedene Aktionen aus.

    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);
        }
    }
39

Sie haben Recht, dass Überlastung nicht die Antwort ist.

Weder ist vorrangig. Überschreiben ist das Mittel, mit dem Sie Polymorphismus erhalten. Polymorphismus ist die Fähigkeit eines Objekts, das Verhalten je nach Typ zu variieren. Dies lässt sich am besten demonstrieren, wenn der Aufrufer eines Objekts, das Polymorphismus aufweist, nicht weiß, um welchen bestimmten Typ es sich handelt.

13
Alex B

Insbesondere wenn Sie überladen oder überschreiben, ergibt dies kein vollständiges Bild. Polymorphismus ist einfach die Fähigkeit eines Objekts, sein Verhalten basierend auf seinem Typ zu spezialisieren.

Ich würde einigen Antworten hier nicht zustimmen, da Überladung eine Form von Polymorphismus (parametrischer Polymorphismus) ist, wenn eine Methode mit demselben Namen sich unterschiedlich verhalten kann und unterschiedliche Parametertypen ergibt. Ein gutes Beispiel ist das Überladen von Operatoren. Sie können "+" definieren, um verschiedene Parametertypen zu akzeptieren, z. B. Zeichenfolgen oder Int-Werte. Basierend auf diesen Typen verhält sich "+" anders.

Der Polymorphismus umfasst auch Vererbungs- und Überschreibungsmethoden, obwohl diese im Basistyp abstrakt oder virtuell sein können. In Bezug auf vererbungsbasierten Polymorphismus unterstützt Java nur die Vererbung einzelner Klassen und beschränkt das polymorphe Verhalten auf das einer einzelnen Kette von Basistypen. Java unterstützt die Implementierung von mehreren Schnittstellen, die noch eine andere Form von polymorphem Verhalten ist.

10
Peter Meyer

Polymorphismus bedeutet einfach "Viele Formen".

Es ist keine Vererbung erforderlich, um ... zu erreichen, da die Schnittstellenimplementierung, bei der es sich überhaupt nicht um Vererbung handelt, polymorphen Anforderungen dient. Die Schnittstellenimplementierung erfüllt wohl die polymorphen Anforderungen "besser" als die Vererbung.

Würden Sie zum Beispiel eine Superklasse erstellen, um alle Dinge zu beschreiben, die fliegen können? Ich sollte nicht denken. Am besten erstellen Sie eine Oberfläche, die den Flug beschreibt, und lassen Sie sie dabei.

Da Schnittstellen das Verhalten beschreiben und Methodennamen das Verhalten (für den Programmierer) beschreiben, ist es nicht allzu schwierig, das Überladen von Methoden als eine geringere Form des Polymorphismus zu betrachten.

7
BillC

Das klassische Beispiel, Hunde und Katzen sind Tiere, Tiere haben die Methode makeNoise. Ich kann durch eine Reihe von Tieren iterieren, die makeNoise für sie aufrufen, und davon ausgehen, dass sie dort die entsprechende Implementierung durchführen würden.

Die Vorwahl muss nicht wissen, um welches Tier es sich handelt.

Das halte ich für Polymorphismus.

6
Brian G

Weder:

Überladen ist, wenn Sie den gleichen Funktionsnamen haben, der verschiedene Parameter annimmt.

Überschreiben ist, wenn eine untergeordnete Klasse die Methode eines Elternteils durch eine eigene ersetzt (dies an sich stellt keinen Polymorphismus dar).

Polymorphismus ist eine späte Bindung, z.B. Die übergeordneten Methoden der Basisklasse werden aufgerufen, aber erst zur Laufzeit weiß die Anwendung, was das eigentliche Objekt ist - es kann sich um eine untergeordnete Klasse handeln, deren Methoden unterschiedlich sind. Dies liegt daran, dass jede untergeordnete Klasse verwendet werden kann, in der eine Basisklasse definiert ist.

In Java) sehen Sie viel Polymorphismus mit der Collections-Bibliothek:

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

List ist die Basisklasse, der Compiler hat keine Ahnung, ob Sie eine verknüpfte Liste, einen Vektor, ein Array oder eine benutzerdefinierte Listenimplementierung zählen, solange sie sich wie eine Liste verhält:

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

Wenn Sie überladen wären, hätten Sie:

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

und die richtige Version von countStuff () würde vom Compiler ausgewählt, um den Parametern zu entsprechen.

4
jpeacock

Polymorphismus ist die Fähigkeit eines Objekts, in mehreren Formen zu erscheinen. Dabei werden Vererbung und virtuelle Funktionen verwendet, um eine Familie von Objekten zu erstellen, die ausgetauscht werden können. Die Basisklasse enthält die Prototypen der virtuellen Funktionen, möglicherweise nicht implementiert oder mit Standardimplementierungen, wie es die Anwendung vorschreibt, und die verschiedenen abgeleiteten Klassen implementieren sie jeweils unterschiedlich, um unterschiedliche Verhaltensweisen zu beeinflussen.

4
mxg

Der Begriff Überladung bezieht sich auf mehrere Versionen von etwas mit demselben Namen, normalerweise Methoden mit unterschiedlichen Parameterlisten

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

Diese Funktionen können also das Gleiche tun, aber Sie haben die Möglichkeit, sie mit einer ID oder einem Namen aufzurufen. Hat nichts mit Vererbung, abstrakten Klassen usw. zu tun.

Überschreiben bezieht sich normalerweise auf Polymorphismus, wie Sie in Ihrer Frage beschrieben haben

3
Clyde

Ich denke, Leute, Sie mischen Konzepte. Polymorphismus ist die Fähigkeit eines Objekts, sich zur Laufzeit anders zu verhalten. Dazu benötigen Sie zwei Voraussetzungen:

  1. Late Binding
  2. Vererbung

Allerdings bedeutet Überladen etwas anderes als Übersteuern, abhängig von der Sprache, die Sie verwenden. Zum Beispiel in Java existiert nicht überschreiben aber überladen. überladen Methoden mit unterschiedlicher Signatur zu seiner Basisklasse sind in der Unterklasse verfügbar. Andernfalls wären sie überschrieben (Bitte beachten Sie, dass es jetzt keine Möglichkeit gibt, Ihre Basisklassenmethode von außerhalb des Objekts aufzurufen.).

In C++ ist dies jedoch nicht der Fall. Jede überladene Methode, unabhängig davon, ob die Signatur gleich ist oder nicht (unterschiedlicher Betrag, unterschiedlicher Typ), ist auch überschrieben. Das heißt, heute ist die Methode der Basisklasse in der Unterklasse nicht mehr verfügbar, wenn sie offensichtlich von außerhalb des Unterklassenobjekts aufgerufen wird.

Die Antwort ist also, wenn es um Java use overloading geht. In jeder anderen Sprache kann es anders sein als in c ++

2
user1154840

Der Polymorphismus wird in diesem Beitrag zwar bereits ausführlich erklärt, aber ich möchte mehr Nachdruck darauf legen, warum ein Teil davon ist.

Warum Polymorphismus in jeder OOP Sprache so wichtig ist.

Versuchen wir, eine einfache Anwendung für ein Fernsehgerät mit und ohne Vererbung/Polymorphismus zu erstellen. Posten Sie jede Version der Anwendung, wir machen eine kleine Retrospektive.

Angenommen, Sie sind Softwareingenieur bei einem Fernsehunternehmen und müssen Software für die Lautstärkeregler, die Helligkeitsregler und die Farbregler schreiben, um deren Werte auf Benutzerbefehl zu erhöhen oder zu verringern.

Sie beginnen mit dem Schreiben von Klassen für jede dieser Funktionen, indem Sie sie hinzufügen

  1. set: - Zum Einstellen eines Wertes für einen Controller. (Angenommen, dieser hat einen Controller-spezifischen Code.)
  2. get: - Um einen Wert eines Controllers zu erhalten. (Angenommen, dieser hat einen Controller-spezifischen Code.)
  3. anpassen: - Um die Eingabe zu validieren und einen Controller einzustellen. (Generische Validierungen .. unabhängig von Controllern)
  4. benutzereingabezuordnung mit Controllern: - Um Benutzereingaben abzurufen und Controller entsprechend aufzurufen.

Anwendungsversion 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;
        }

    }
    }
}

Jetzt können Sie unsere erste Version der Arbeitsanwendung bereitstellen. Zeit, die bisher geleistete Arbeit zu analysieren.

Probleme in der TV-Anwendung Version 1

  1. Der Anpassungscode (Int-Wert) ist in allen drei Klassen doppelt vorhanden. Sie möchten die Code-Duplizität minimieren. (Aber Sie haben nicht an gemeinsamen Code gedacht und ihn in eine Superklasse verschoben, um doppelten Code zu vermeiden.)

Sie entscheiden sich, damit zu leben, solange Ihre Anwendung wie erwartet funktioniert.

Manchmal kommt Ihr Chef zu Ihnen zurück und bittet Sie, der vorhandenen Anwendung eine Rücksetzfunktion hinzuzufügen. Zurücksetzen würde alle drei Controller auf ihre jeweiligen Standardwerte setzen.

Sie schreiben eine neue Klasse (ResetFunctionV2) für die neue Funktionalität und ordnen den Benutzereingabezuordnungscode für diese neue Funktion zu.

Anwendungsversion 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;
            }

        }
    }
}

So haben Sie Ihre Anwendung mit der Reset-Funktion fertig. Aber jetzt fängst du an, das zu realisieren

Probleme in der TV-Anwendung Version 2

  1. Wenn ein neuer Controller in das Produkt eingeführt wird, müssen Sie den Feature-Code Zurücksetzen ändern.
  2. Wenn die Anzahl der Controller sehr hoch wird, könnte es Probleme geben, die Referenzen der Controller zu speichern.
  3. Der Reset-Feature-Code ist eng mit dem Code der Controller-Klasse verknüpft (um Standardwerte abzurufen und festzulegen).
  4. Die Reset-Feature-Class (ResetFunctionV2) kann auf eine andere Methode der Controller-Class zugreifen (adjust), was unerwünscht ist.

Gleichzeitig hören Sie von Ihrem Chef, dass Sie möglicherweise eine Funktion hinzufügen müssen, bei der jeder der Controller beim Start über das Internet nach der neuesten Treiberversion aus dem vom Unternehmen gehosteten Treiber-Repository suchen muss.

Jetzt denken Sie, dass diese neue Funktion mit der Funktion "Zurücksetzen" vergleichbar ist und dass Probleme mit der Anwendung (V2) multipliziert werden, wenn Sie Ihre Anwendung nicht neu faktorisieren.

Sie beginnen mit der Verwendung der Vererbung, um die polymorphen Fähigkeiten von Java zu nutzen, und fügen eine neue abstrakte Klasse (ControllerV3) hinzu

  1. Deklarieren Sie die Signatur der Methode get und set.
  2. Enthält die Implementierung der Anpassungsmethode, die zuvor auf alle Controller repliziert wurde.
  3. Deklarieren Sie die setDefault-Methode, damit die Rücksetzfunktion mithilfe des Polymorphismus problemlos implementiert werden kann.

Mit diesen Verbesserungen haben Sie Version 3 Ihrer TV-Anwendung bereit.

Anwendungsversion 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;
            }

        }
    }
}

Obwohl die meisten der in der Problemliste von V2 aufgelisteten Probleme mit Ausnahme von behoben wurden

Probleme in der TV-Anwendung Version 3

  1. Die Reset-Feature-Class (ResetFunctionV3) kann auf eine andere Methode der Controller-Class zugreifen (anpassen), was unerwünscht ist.

Auch hier möchten Sie dieses Problem lösen, da Sie jetzt eine weitere Funktion (Treiberaktualisierung beim Start) implementieren müssen. Wenn Sie das Problem nicht beheben, wird es auch auf neue Funktionen repliziert.

Sie teilen also den in abstract class definierten Vertrag auf und schreiben 2 Schnittstellen für

  1. Funktion zurücksetzen.
  2. Treiber-Update.

Und lassen Sie sie von Ihrer ersten konkreten Klasse wie folgt implementieren

Anwendungsversion 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;
            }

        }
    }
}

Nun wurde das gesamte Problem, mit dem Sie konfrontiert waren, angesprochen und Sie erkannten, dass Sie mit der Verwendung von Vererbung und Polymorphismus dies könnten

  1. Halten Sie verschiedene Teile der Anwendung lose miteinander verbunden. (Die Komponenten der Reset- oder Treiberaktualisierungsfunktion müssen nicht über die tatsächlichen Controller-Klassen (Lautstärke, Helligkeit und Farbe) informiert werden. Jede Klasse, die OnReset oder OnStart implementiert, ist für die Reset- oder Treiberaktualisierungsfunktion zulässig Komponenten).
  2. Die Anwendungserweiterung wird einfacher. (Das Hinzufügen eines neuen Controllers wirkt sich nicht auf das Zurücksetzen oder die Treiberaktualisierung aus. Außerdem können Sie jetzt ganz einfach neue hinzufügen.)
  3. Abstraktionsebene beibehalten. (Die Funktion "Zurücksetzen" kann nur die setDefault-Methode von Controllern anzeigen. Die Funktion "Zurücksetzen" kann nur die checkForDriverUpdate-Methode von Controllern anzeigen.)

Hoffe das hilft :-)

2
Developer

was ist Polymorphismus?

Von Java Tutorial

Die Wörterbuchdefinition des Polymorphismus bezieht sich auf ein Prinzip in der Biologie, bei dem ein Organismus oder eine Art viele verschiedene Formen oder Stadien haben kann. Dieses Prinzip kann auch auf objektorientierte Programmierung und Sprachen wie die Java language. Unterklassen einer Klasse können ihr eigenes eindeutiges Verhalten definieren und doch einige der gleichen Funktionen der Elternklasse teilen.

Unter Berücksichtigung der Beispiele und Definitionen sollte overriding als Antwort akzeptiert werden.

Bezüglich Ihrer zweiten Frage:

WENN Sie eine abstrakte Basisklasse hatten, die eine Methode ohne Implementierung definiert hat, und Sie diese Methode in der Unterklasse definiert haben, ist das immer noch ein Überschreiben?

Es sollte als übergeordnet bezeichnet werden.

Schauen Sie sich dieses Beispiel an, um verschiedene Arten des Überschreibens zu verstehen.

  1. Basisklasse stellt keine Implementierung bereit und Unterklasse muss vollständige Methode überschreiben - (Zusammenfassung)
  2. Die Basisklasse stellt die Standardimplementierung bereit, und die Unterklasse kann das Verhalten ändern
  3. Die Unterklasse erweitert die Implementierung der Basisklasse, indem sie als erste Anweisung super.methodName() aufruft
  4. Die Basisklasse definiert die Struktur des Algorithmus (Template-Methode) und die Unterklasse überschreibt einen Teil des Algorithmus

code-Auszug:

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();
        }       
    }
}

ausgabe:

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
Ravindra babu

überladung ist, wenn Sie 2 Methoden mit dem gleichen Namen, aber unterschiedlichen Parametern definieren

beim Überschreiben ändern Sie das Verhalten der Basisklasse über eine gleichnamige Funktion in einer Unterklasse.

Polymorphismus ist also mit Überschreiben verbunden, aber nicht wirklich mit Überladen.

Wenn mir jedoch jemand eine einfache Antwort mit "Überschreiben" für die Frage "Was ist Polymorphismus?" Ich würde um weitere Erklärung bitten.

2
Matt

durch das Überschreiben wird eher eine geerbte Methode ausgeblendet, indem eine Methode mit demselben Namen und derselben Signatur deklariert wird wie die Methode der höheren Ebene (Supermethode). Dadurch wird der Klasse ein polymorphes Verhalten hinzugefügt. Mit anderen Worten, die Entscheidung, welche Level-Methode aufgerufen werden soll, wird zur Laufzeit und nicht zur Kompilierungszeit getroffen. Dies führt zum Konzept der Schnittstelle und Implementierung.

2
Genjuro

Polymorphismus ist wahrscheinlicher, was was bedeutet betrifft ... um in Java ZU ÜBERSPRINGEN

Es geht um das unterschiedliche Verhalten des SAME-Objekts in unterschiedlichen Situationen. (In der Programmierweise können Sie verschiedene ARGUMENTE aufrufen.)

Ich denke, das folgende Beispiel wird Ihnen helfen zu verstehen ... Obwohl es nicht PURE ist Java code ...

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

Aber wenn wir das ARGUMENT ändern ... wird sich das VERHALTEN ändern ...

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

Die Person (hier das "Objekt") ist gleich ...

1
Rajan

Polymorphismus ist eine Vielzahl von Implementierungen eines Objekts oder man könnte sagen, mehrere Formen eines Objekts. Nehmen wir an, Sie haben die Klasse Animals als abstrakte Basisklasse und sie hat eine Methode namens movement(), die definiert, wie sich das Tier bewegt. In Wirklichkeit haben wir verschiedene Arten von Tieren und sie bewegen sich auch unterschiedlich, einige mit 2 Beinen, andere mit 4 und einige ohne Beine, usw .. Um verschiedene movement() von jedem Tier auf der Erde zu definieren, wir müssen Polymorphismus anwenden. Sie müssen jedoch mehr Klassen definieren, z. B. Klasse DogsCatsFish usw. Dann müssen Sie diese Klassen aus der Basisklasse Animals erweitern und ihre überschreiben Methode movement() mit einer neuen Bewegungsfunktionalität basierend auf jedem Tier, das Sie haben. Sie können dazu auch Interfaces verwenden. Das Schlüsselwort hier ist "Overriding", Überladung ist anders und wird nicht als Polymorphismus betrachtet. Bei Überladung können Sie mehrere Methoden "mit demselben Namen", aber mit unterschiedlichen Parametern für dasselbe Objekt oder dieselbe Klasse definieren.

1
SolidSnake

Polymorphismus bezieht sich auf die Fähigkeit einer Sprache, unterschiedliche Objekte unter Verwendung einer einzigen Schnittstelle einheitlich zu behandeln. als solches ist es mit Überschreiben verbunden, also ist die Schnittstelle (oder die Basisklasse) polymorph, der Implementierer ist das Objekt, das überschreibt (zwei Gesichter derselben Medaille)

wie auch immer, der Unterschied zwischen den beiden Begriffen lässt sich besser mit anderen Sprachen wie c ++ erklären: Ein polymorphes Objekt in c ++ verhält sich wie das Gegenstück Java), wenn die Basisfunktion virtuell ist, die Methode jedoch Nicht virtuell Der Codesprung wird aufgelöst statisch und der wahre Typ wird zur Laufzeit nicht überprüft. Daher beinhaltet der Polymorphismus die Möglichkeit, dass sich ein Objekt abhängig von der für den Zugriff verwendeten Schnittstelle anders verhält. Lassen Sie mich ein Beispiel geben im Pseudocode:

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

(Angenommen, makeRumor ist NICHT virtuell)

Java bietet diese Ebene des Polymorphismus (auch Object Slicing genannt) nicht wirklich an.

tier a = neuer Hund (); Hund b = neuer Hund ();

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

in beiden Fällen wird nur woff ausgegeben, da sich a und b auf Klassenhund beziehen

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());

    }
}
0
bharanitharan