2010-08-17 17 views
11

Dlaczego jest drukowany jako ostatni "Jestem klasą dziecięcą". ?Dziedziczenie 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(); 
    } 
} 

wyjściowa:

From Derived 

Child Constructor. 

I'm a Parent Class. 

I'm a Child Class. 

I'm a Parent Class. 

I'm a Child Class. 

Odpowiedz

15

Ponieważ jest przykładem polymorphism (koniec wiązania). Podczas kompilacji określasz, że obiekt jest typu Parent i dlatego można wywoływać tylko metody zdefiniowane w Parent. Ale w czasie wykonywania, gdy dochodzi do "wiązania", metoda jest wywoływana na obiekcie, który jest typu Child, niezależnie od tego, w jaki sposób jest on przywoływany w kodzie.

Częścią, która Cię zaskakuje jest to, dlaczego nadrzędna metoda powinna zostać wywołana w czasie wykonywania. W Javie (w przeciwieństwie do C# i C++) wszystkie metody są virtual i stąd wywoływana jest metoda nadrzędna. Zobacz this example, aby zrozumieć różnicę.

+1

Dobre pytanie i dobra odpowiedź. Jest to również dobre w prawdziwych programach; Twój kod może się zepsuć, jeśli przez przypadek masz jakiś kod, który nazwał implementację rodzica. – Tormod

2

Zarówno:

child.print(); 

i

((Parent)child).print(); 

powinien zwrócić:

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

w tej kolejności.

Rzucanie obiektu na jego klasę podstawową nie zmienia sposobu wywołania metody.

W tym przypadku nawet po odlaniu zostanie wywołana metoda drukowania podrzędnego, a nie rodzic.

+0

Co mnie zdezorientowało to, że ten sam kod w C# drukuje tylko "Jestem klasą nadrzędną" – vad

+0

Dziedziczenie i polimorfizm działa dokładnie tak samo w języku C#. Jednak C# wymaga wirtualnego słowa kluczowego dla metod, które chcesz zastąpić w dziedziczeniu podklas, więc domyślam się, że nie używałeś wirtualnego, stąd masz inny wynik. – vicsz

0

Nawet jeśli oddałeś dziecko rodzicowi, nie zmienia to jego implementacji metody. To w rzeczywistości nie czyni z rodzica. Dlatego możesz zrobić coś takiego:

Image img = new BufferedImage(...); 

Mimo że obraz jest abstrakcyjny, zdjęcie jest nadal obrazem buforowanym.

0

Nawet jeśli rzutujesz go jako klasę nadrzędną, nie oznacza to, że będzie używać funkcji rodzica - traktuje obiekt tylko jako obiekt nadrzędny.

Mówiąc ((Rodzic) dziecko) .print(); mówisz "Traktuj ten obiekt jako obiekt nadrzędny, a nie jako obiekt podrzędny". Nie "Użyj implementacji metody nadrzędnej"

W ten sposób, jeśli obiekt podrzędny miał inne metody, nie mógłbyś ich wywołać. Ale ponieważ print() jest metodą rodzica, wciąż możesz go nazwać, ale używa on rzeczywistej implementacji obiektu (nie klasy, do której został rzucony).

0

w języku Java, jeśli wywołujemy dowolną metodę na jednym obiekcie, to jej wywołania metoda za pomocą sub sub obiektu ............... tutaj:

Obiekt | | Rodzic | | Dziecko < - sub najbardziej przedmiot

Przypadek 1 ::

Child dziecko = new Child();

child.print(); 

to wywołanie metody klasy dziecko druk za pomocą obiektu podrzędnego ... dziecko jest poniżej najbardziej tak drukuje

wyjście ::

Jestem klasa nadrzędna. Jestem klasą dziecięcą.

Objaśnienie: Metoda potomna nazywa metodę nadrzędną z powodu super.print(); metoda więc pierwsza linia to jestem klasa nadrzędna. po zakończeniu kontroli metody rodzica metoda powraca do metody podrzędnej i drukuje Jestem klasą dziecka.

Przypadek 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. 

Wyjaśnienie: Od dziecka metodą jest wywołanie metody nadrzędnego powodu super.print(); metoda więc pierwsza linia to jestem klasa nadrzędna. po zakończeniu kontroli metody rodzica metoda powraca do metody podrzędnej i drukuje Jestem klasą dziecka.