2010-08-17 22 views
11

Perché è l'ultima stampa "I'm a Child Class". ?ereditarietà Java

public class Parent 
{ 
    String parentString; 
    public Parent() 
    { 
     System.out.println("Parent Constructor."); 
    } 

    public Parent(String myString) 
    { 
     parentString = myString; 
     System.out.println(parentString); 
    } 

    public void print() 
    { 
     System.out.println("I'm a Parent Class."); 
    } 
} 

public class Child extends Parent 
{ 
    public Child() { 
     super("From Derived"); 
     System.out.println("Child Constructor."); 
    } 

    public void print() 
    { 
     super.print(); 
     System.out.println("I'm a Child Class."); 
    } 

    public static void main(String[] args) 
    { 
     Child child = new Child(); 
     child.print(); 
     ((Parent)child).print(); 
    } 
} 

uscita:

From Derived 

Child Constructor. 

I'm a Parent Class. 

I'm a Child Class. 

I'm a Parent Class. 

I'm a Child Class. 

risposta

15

Perché questo è un esempio di polymorphism (associazione tardiva). Al momento della compilazione si specifica che l'oggetto è di tipo Parent e pertanto può chiamare solo i metodi definiti in Parent. Ma in fase di esecuzione, quando avviene il "binding", il metodo viene chiamato sull'oggetto, che è di tipo Child indipendentemente da come viene fatto riferimento nel codice.

La parte che ti sorprende è il motivo per cui il metodo di override deve essere richiamato in fase di esecuzione. In Java (a differenza di C# e C++) tutti i metodi sono virtual e quindi viene chiamato il metodo di override. Vedi this example per capire la differenza.

+1

Buona domanda e buona risposta. Questa è anche una buona cosa nei programmi reali; il tuo codice potrebbe rompersi se per caso avessi un codice che ha chiamato l'implementazione genitore. – Tormod

2

Entrambi:

child.print(); 

e

((Parent)child).print(); 

dovrebbe restituire:

I'm a Parent Class. 
I'm a Child Class. 

In tale ordine.

Il casting di un oggetto nella relativa classe base non cambia la chiamata al metodo eseguita.

In questo caso, anche dopo il cast, viene chiamato il metodo di stampa figlio e non il genitore.

+0

Ciò che mi ha confuso è che lo stesso codice in C# stampa solo "I'm Parent Class" – vad

+0

L'ereditarietà e il polimorfismo funzionano esattamente allo stesso modo in C#. Tuttavia, C# richiede la parola chiave virtuale per i metodi che desideri sovrascrivere nell'assegnazione di sottoclassi, quindi suppongo che tu non abbia usato virtuale, quindi hai ottenuto il risultato diverso. – vicsz

0

Anche se si esegue il cast del figlio su Padre questo non modifica l'implementazione del metodo. Questo in realtà non lo rende un genitore. Questo è il motivo per cui si può fare qualcosa di simile:

Image img = new BufferedImage(...); 

Anche se L'immagine è img astratta è ancora un BufferedImage sotto.

0

Anche se si sta casting come la classe padre, che non significa che userà functions-- del suo genitore si tratterà solo l'oggetto come un genitore.

Dicendo ((Parent) child) .print(); stai dicendo "Tratta questo oggetto come oggetto padre, non come oggetto figlio". Non "Utilizza le implementazioni del metodo principale"

Pertanto, se l'oggetto figlio avesse altri metodi, non sarebbe possibile chiamarli. Ma poiché print() è un metodo del genitore, puoi comunque chiamarlo, ma usa l'implementazione dell'oggetto reale (non della classe a cui è stato assegnato il cast).

0

in java se chiamiamo qualsiasi metodo su un oggetto allora le sue chiamate il metodo utilizzando sub più oggetto ............... qui:

Oggetto | | genitore | | Bambino < - sub più oggetto

Caso 1 ::

bambino Bambino = new Bambino();

child.print(); 

questa chiamata metodo di classe bambino di stampa utilizzando oggetto figlio ... figlio è sub più così esso stampa

uscita ::

Sono una classe genitore. Sono un bambino.

Spiegazione: Dal metodo figlio chiama il metodo padre a causa di super.print(); metodo quindi la prima riga è che sono una classe padre. dopo il completamento del metodo genitore, i controlli di esecuzione ritornano al metodo figlio e stampa I'm a Child Class.

Caso 2 ::

((Parent)child).print(); 
if we call like this jvm calls print() method by using sub most object here sub most object is child object so it prints 

output:: 
      I'm a Parent Class. 
      I'm a Child Class. 

Spiegazione: Da bambino il metodo si chiama il metodo genitore a causa di super.print(); metodo quindi la prima riga è che sono una classe padre. dopo il completamento del metodo genitore, i controlli di esecuzione ritornano al metodo figlio e stampa I'm a Child Class.

Problemi correlati