2011-08-02 18 views
14

Podczas eksploracji pytań SCJP natknąłem się na to zachowanie, które znalazłem dziwnym.Wydanie Java Inheritance

I zadeklarowały dwie klasy element i Bolt następująco:

class Item { 
    int cost = 20; 

    public int getCost() { 
     return cost; 
    } 
} 

class Bolt extends Item { 
    int cost = 10; 

    public int getCost() { 
     return cost; 
    } 
} 

i próbował uzyskać dostęp do wartości kosztów dwukrotnie

public class Test { 
    public static void main(String[] args) { 
     Item obj = new Bolt(); 
     System.out.println(obj.cost); 
     System.out.println(obj.getCost()); 
    } 
} 

Wyjście mogę to 20 10. mogę” t zrozumieć, jak to się dzieje.

+0

Nie. @Override jest tylko wskazówką dla kompilatora, że ​​ta metoda ma zastąpić inną, i że powinna spowodować błąd, jeśli tak nie jest. Ale gdy metody mają tę samą sygnaturę, druga z nich zastępuje pierwszą. Adnotacje nie istniały przed Java 5. –

+0

@netbrain, metoda getClost podklasy działa dobrze. Byłem ciekawy wyniku bezpośredniego wywołania obj.cost. Ale, jak mówi Sanjay, wynika to z faktu, że polimorfizm w czasie wykonywania dotyczy tylko metod, a nie pól. –

Odpowiedz

19

obj jest odniesienie typu Item stąd pierwszy 20 od wartości cost dziedzinie Item wynosi 20. Druga wartość jest 10 ponieważ typ czas pracy obj jest Bolt i stąd getCost() wywołuje getCost z Bolt klasy (od Bolt rozszerza Item).

W skrócie, polimorfizm runtime dotyczy tylko elementów składowych (przesłanianie metody), a nie pól instancji.

+1

tak. i jeszcze jeden powód, by unikać pól publicznych. –

+0

A więc w obiekcie Bolt są dwa pola kosztów? – bcr

+0

Z perspektywy szczegółowości wdrożenia, tylko * jeden * obiekt jest tworzony po wypowiedzeniu 'new Bolt()'. Ale tak, podklasa jest prawie świadoma pól/metod swoich super-klasowych hostów. Możesz to sprawdzić, dodając trzeci kod 'sysout' w swoim kodzie:' System.out.println (((Bolt) obj) .cost) ' –

7

Pola klas nie biorą udziału w grze polimorfizmów. Metody mają.

Tak więc, po wejściu do pola następuje przejście do tego, które jest zdefiniowane w klasie bazowej, ponieważ typ obiektu to Item. Kiedy wywołujesz metodę, otrzymujesz rzeczywistą wartość, ponieważ wywołujesz metodę używając polimorfizmu.

Wniosek:

Pola są zawsze prywatne. Jeśli chcesz uzyskać dostęp do metody zapisu pola.

+0

To, i odpowiedź Sanjaya wyjaśnił mi to. –