5

Gemäß der Regel können Parameter beim Überschreiben einer Methode in der Unterklasse nicht geändert werden und müssen mit denen in der Superklasse identisch sein. Was passiert, wenn wir die Unterklasse des Parameters beim Überschreiben der Methode übergeben? Wird es als Überladen oder Überschreiben bezeichnet?Können wir in Java eine Methode überschreiben, indem wir die Unterklasse des in der Superklassenmethode verwendeten Parameters übergeben?

Basierend auf meiner Abfrage habe ich einen Code unten geschrieben.
Ich erwartete die Ausgabe als "Hund isst Fleisch Essen", aber zu meiner Überraschung ist die Ausgabe "Tier ißt Fleisch Essen" Will schätzen, wenn jemand erklären kann, wie Animal-Methode aufgerufen wird, wenn das zugewiesene Objekt vom Typ Hund ist?

class Food { 
     public String toString(){ 
      return "Normal Food"; 
     } 
    } 

    class Flesh extends Food { 
     public String toString(){ 
      return "Flesh Food"; 
     } 
    } 

    class Animal { 
     public void eat(Food food){ 
      System.out.println("Animal eats "+ food); 
     } 
    } 

    class Dog extends Animal{ 

     public void eat(Flesh flesh){ 
      System.out.println("Dog eats "+ flesh); 
     } 
    } 

    public class MyUtil { 

     public static void main(String[] args) { 

      Animal animal = new Dog(); 

      Flesh flesh = new Flesh(); 

      animal.eat(flesh); 
     } 
    } 
+1

Sie den Code bereits geschrieben haben - probieren Sie es und finden Sie heraus, was der Compiler sagt. – childofsoong

+0

siehe "Besuchermuster" – ZhongYu

+0

Der Compiler beschwert sich nichts. Eigentlich läuft das Programm, deshalb kann ich die Ausgabe sehen, aber es ist komisch. Wenn ich die Methode explizit als @Override annotieren, beschwert sich der Compiler, dh er überschreibt nicht. Sie werden auch überrascht sein. Kopieren Sie einfach den Code in Ihre Eclipse, erraten Sie die Ausgabe und führen Sie dann die tatsächliche Ausgabe aus und überprüfen Sie sie. –

Antwort

3

Nein, können wir in diesem Fall nicht, dass Sie es durch Zugabe von @Override über dem essen Methode in Klasse Hund überprüfen so Kompilierungsfehler wie folgt angezeigt wird:

@Override 
public void eat(Flesh flesh){ 
    System.out.println("Dog eats "+ flesh); 
} 

Stellen Sie sicher, dass in Überschreibung Die Parameter sollten als übergeordnete Klasse in Typ und Reihenfolge angegeben werden.

8

Die Methode eat in Dog überschreibt nicht die Methode eat in Animal. Dies liegt daran, dass die Argumente unterschiedlich sind (einer benötigt Flesh, der andere erfordert Food).

Die eat Methoden sind Überladungen.

Die Auswahl zwischen Überladungen erfolgt zur Kompilierzeit, nicht zur Laufzeit. Es ist nicht basierend auf der tatsächlichen Klasse des Objekts, auf dem die Methode aufgerufen wird, sondern die Art der Kompilierung (wie die Variable deklariert wird).

animal hat Kompilierzeit Typ Animal. Wir wissen das, weil die Deklaration der Variablen animalAnimal animal = ... war. Die Tatsache, dass es tatsächlich ein Dog ist, ist irrelevant - es ist die Version eat in Animal, die aufgerufen werden muss.

Auf der anderen Seite, die toString Methode in Fleshtut die toString Methode in Food außer Kraft setzen.

Wenn eine Methode eine andere überschreibt, bestimmt die tatsächliche Klasse des Objekts, für das die Methode aufgerufen wird, welche Version ausgeführt wird.

Im eat Methode der Animal, obwohl das Argument Kompilierung-Typ hat Food, wenn Sie eine Instanz von Flesh es passieren, es ist die toString Methode in Flesh ist, die ausgeführt wird.

Daher erhalten Sie die Nachricht "Animal eats Flesh Food".

+0

Danke für die kristallklare Erklärung !! –

3

Sie können die Annotation @override verwenden, um den Compiler zu informieren, dass Sie versuchen, eine Methode in der Superklasse zu überschreiben.

z.B.

class Dog extends Animal{ 

    @Override 
    public void eat(Flesh flesh){ 
     System.out.println("Dog eats "+ flesh); 
    } 
} 

In Ihrem Code, jetzt wird der Compiler einen Fehler erzeugen, da diese Methode nicht eat enthebt, können Sie den gleichen Parametertyp haben müssen.

jedoch die Änderung der Flesh Parameter Food Art wird das Problem beheben:

class Dog extends Animal{ 

    @Override 
    public void eat(Food food){ 
     System.out.println("Dog eats "+ food); 
    } 
} 

Jetzt können Sie folgendes tun:

public class MyUtil { 

    public static void main(String[] args) { 

     Animal animal = new Dog(); 

     Food food = new Flesh(); 

     animal.eat(food); 
    } 
} 
1

Wenn Sie dies tun: Animal animal = new Dog(); es ist Upcasting.

Und Sie überschreiben die Methode nicht

public void eat(Flesh flesh){ 
    System.out.println("Dog eats "+ flesh); 
} 

so nennt es die Methode eat(Food food) von Animal