5

Come per la regola, ignorando un metodo nella sottoclasse, i parametri non possono essere modificati e devono essere uguali a quelli della super classe. Cosa succede se passiamo sottoclasse di parametri durante l'override del metodo? Sarà chiamato sovraccarico o override?In java, è possibile sovrascrivere un metodo passando la sottoclasse del parametro utilizzato nel metodo super-classe?

Sulla base della mia richiesta ho scritto del codice qui sotto.
Mi aspettavo che l'uscita fosse "Cane mangia carne" ma con mia sorpresa l'uscita è "Animali mangia carne" Apprezzerà se qualcuno può spiegare come viene chiamato il metodo Animal quando l'oggetto assegnato è di tipo Cane?

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

Hai già scritto il codice - provare e scoprire che cosa dice il compilatore. – childofsoong

+0

vedere "modello visitatore" – ZhongYu

+0

Il compilatore non si lamenta di nulla. In realtà il programma viene eseguito è per questo che sono in grado di vedere l'output ma è strano. Se annoto esplicitamente il metodo come @Override, il compilatore si lamenta, ciò significa che non è prioritario. Anche tu sarai sorpreso. Basta copiare il codice in eclissi, indovinare l'output e quindi eseguire e verificare l'output effettivo. –

risposta

3

No, non possiamo in questo caso è possibile controllare con l'aggiunta @Override sopra il metodo di mangiare in classe Dog così apparirà errore di compilazione in questo modo:

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

Assicurarsi che in sostituzione i parametri dovrebbero essere come classe genitore nel tipo e nell'ordine.

8

Il metodo eat in Dog non sovrascrive il metodo eat in Animal. Questo perché gli argomenti sono diversi (uno richiede Flesh, l'altro richiede Food).

I metodi eat sono sovraccarichi.

La scelta tra i sovraccarichi avviene in fase di compilazione, non in fase di esecuzione. È non in base alla classe effettiva dell'oggetto su cui è stato richiamato il metodo, ma il tipo in fase di compilazione (come viene dichiarata la variabile).

animal ha il tipo di registrazione Animal. Lo sappiamo perché la dichiarazione della variabile animal era Animal animal = .... Il fatto che sia effettivamente un Dog è irrilevante: è la versione di eat in Animal che deve essere richiamata.

D'altra parte, il metodo toString in Fleshfa ignorare il metodo toString in Food.

Quando un metodo esegue l'override di un altro, è la classe effettiva dell'oggetto su cui viene invocato il metodo che determina quale versione viene eseguita.

Nel metodo di Animaleat, anche se l'argomento ha compilazione tempo tipo Food, se si passa un'istanza Flesh ad esso, è il metodo toString in Flesh che eseguirà.

Pertanto viene visualizzato il messaggio "Animal eats Flesh Food".

+0

Grazie per la spiegazione cristallina !! –

3

È possibile utilizzare l'annotazione @override per informare il compilatore che si sta tentando di sovrascrivere un metodo all'interno della superclasse.

ad es.

class Dog extends Animal{ 

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

Nel codice, ora il compilatore genererà un errore, perché questo metodo non sostituisce eat, è necessario avere lo stesso tipo di parametro.

Tuttavia, modificando il parametro Flesh a Food tipo risolverà il problema:

class Dog extends Animal{ 

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

Ora è possibile effettuare le seguenti operazioni:

public class MyUtil { 

    public static void main(String[] args) { 

     Animal animal = new Dog(); 

     Food food = new Flesh(); 

     animal.eat(food); 
    } 
} 
1

Quando si esegue questa operazione: Animal animal = new Dog(); è upcasting.

E non l'override del metodo

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

così viene chiamato il metodo eat(Food food) di Animal