377 Stimmen

Polymorphismus vs. Overriding vs. Überladen

In Bezug auf Java, wenn jemand fragt:

Was ist Polymorphismus?

Würde Überlastung o Übergeordnetes eine akzeptable Antwort sein?

Ich glaube, da steckt ein bisschen mehr dahinter.

WENN Sie eine abstrakte Basisklasse haben, die eine Methode ohne Implementierung definiert, und Sie definieren diese Methode in der Unterklasse, ist das immer noch überschreibend?

Ich denke Überlastung ist mit Sicherheit nicht die richtige Antwort.

6voto

mxg Punkte 1267

Polymorphismus ist die Fähigkeit eines Objekts, in mehreren Formen aufzutreten. Dabei werden Vererbung und virtuelle Funktionen eingesetzt, um eine Familie von Objekten zu bilden, die untereinander ausgetauscht werden können. Die Basisklasse enthält die Prototypen der virtuellen Funktionen, möglicherweise unimplementiert oder mit Standardimplementierungen, wie es die Anwendung vorschreibt, und die verschiedenen abgeleiteten Klassen implementieren sie jeweils unterschiedlich, um verschiedene Verhaltensweisen zu bewirken.

5voto

Matt Punkte 2226

Überladung bedeutet, dass Sie 2 Methoden mit demselben Namen, aber unterschiedlichen Parametern definieren

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

Polymorphismus ist also mit Overriding verwandt, aber nicht wirklich mit Overloading.

Wenn mir jedoch jemand auf die Frage "Was ist Polymorphismus?" die einfache Antwort "Overriding" geben würde, würde ich nach weiteren Erklärungen fragen. würde ich um eine weitere Erklärung bitten.

4voto

Jason Peacock Punkte 1753

Weder noch:

Von Überladung spricht man, wenn man denselben Funktionsnamen hat, der verschiedene Parameter benötigt.

Überschreiben bedeutet, dass eine untergeordnete Klasse die Methode einer übergeordneten Klasse durch eine eigene Methode ersetzt (dies stellt an sich noch keinen Polymorphismus dar).

Polymorphismus ist eine späte Bindung, d.h. die Methoden der Basisklasse (Elternklasse) werden aufgerufen, aber erst zur Laufzeit weiß die Anwendung, was das eigentliche Objekt ist - es kann eine Unterklasse sein, deren Methoden anders sind. Dies liegt daran, dass jede Unterklasse dort verwendet werden kann, wo eine Basisklasse definiert ist.

In Java sieht man Polymorphismus häufig in der Sammlungsbibliothek:

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 List verhält:

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

Wenn Sie überlastet wären, hätten Sie das:

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 werden, um den Parametern zu entsprechen.

4voto

Ravindra babu Punkte 45577

Was ist Polymorphismus?

Von java tutorial

Die Wörterbuchdefinition von 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 lässt sich auch auf die objektorientierte Programmierung und Sprachen wie Java anwenden. Unterklassen einer Klasse können ihr eigenes Verhalten definieren und dennoch einige der Funktionen der übergeordneten Klasse nutzen.

Unter Berücksichtigung der Beispiele und der Definition, Übergeordnetes sollte als Antwort akzeptiert werden.

Bezüglich Ihrer zweiten Frage:

WENN Sie eine abstrakte Basisklasse haben, die eine Methode ohne Implementierung definiert, und Sie definieren diese Methode in der Unterklasse, ist das immer noch überschreibend?

Es sollte Overriding genannt werden.

Schauen Sie sich dieses Beispiel an, um die verschiedenen Arten des Overriding zu verstehen.

  1. Die Basisklasse bietet keine Implementierung und die Unterklasse muss die komplette Methode überschreiben - (abstrakt)
  2. Die Basisklasse bietet eine Standardimplementierung und die Unterklasse kann das Verhalten ändern
  3. Die Unterklasse erweitert die Implementierung der Basisklasse durch den Aufruf von super.methodName() als erste Anweisung
  4. Die Basisklasse definiert die Struktur des Algorithmus (Schablonenmethode) und die Unterklasse überschreibt einen Teil des Algorithmus

Codeschnipsel:

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:

3voto

Clyde Punkte 7939

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. Das hat nichts mit Vererbung, abstrakten Klassen usw. zu tun.

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X