Czy nadal jest to polimorfizm?

0

Witam, proszę o rozwianie moich wątpliwości.

Jak wiadomo polimorfizm jest ściśle związany z dziedziczeniem i rzutowaniem w górę. Ogólnie rzecz ujmując do referencji klasy bazowej, przypisujemy odwołanie do obiektu klasy pochodnej.

class B extends A {...}
A a = new B(); // rzutowanie w górę

Klasa A jest typem referencji, a klasa B jest typem faktycznym.

Załóżmy, że chcemy wywołać jakąś metodę np.:

a.doSomething(); // wywołanie polimorficzne metody doSomething()

Jest ona zaimplementowana w klasie A oraz przesłonięta w klasie B. Wówczas JVM sprawdza tą metodę pod kątem faktycznego typu obiektu - sprawdza czy występuje ona w klasie B.

  1. Jeśli tak, wywołuje ją. "Zjawisko" to jest nazywane polimorfizmem.
  2. Jeśli nie (nie została zaimplementowana w klasie B), wywołuje ją z klasy A. Czy dalej mamy tu do czynienia z polimorfizmem? Czy zachodzi on tylko wtedy, gdy metoda wywoływana jest z klasy B?
    Jeśli klasa B zostałaby rozszerzona o dodatkową metodę, której nie ma w klasie A, to aby ją wywołać musielibyśmy skorzystać z rzutowania w dół:
((B) a).doSomething2(); //rzutowanie w dół

W tym przypadku nie ma mowy o zachodzeniu polimorfizmu. Dobrze to rozumiem?

Z góry dzięki za każdą chęć pomocy.

1
witek901 napisał(a):

Jeśli klasa B zostałaby rozszerzona o dodatkową metodę, której nie ma w klasie A, to aby ją wywołać musielibyśmy skorzystać z rzutowania w dół:

((B) a).doSomething2(); //rzutowanie w dół

Nie!
Jeżeli a stworzone jako new A() to dostaniesz komunikat: A cannot be cast to B at ...

2
A a;
// tutaj następuje inicjalizacja a
a.doSomething();

Pytanie: czy wynik a.doSomething() może się różnić w zależności od tego jak a została zainicjalizowana? Jeśli tak to masz polimorfizm.

((B) a).doSomething2();

Czy tutaj jest polimorfizm? Czy wynik tego wywołania różni się w zależności od tego jak a została zainicjalizowana? Jeśli to się skompiluje to zawsze zostanie wywołana metoda z klasy B, bez wzlędu na to czym jest a. Chyba że doSomething2() zostało przeciążone w klasie dziedziczącej po B, o czym pisze @_13th_Dragon 2 posty niżej. Jak widać odpowiedź zależy od kontekstu.

2
twonek napisał(a):
((B) a).doSomething2();

Czy tutaj jest polimorfizm? Czy wynik tego wywołania różni się w zależności od tego jak a została zainicjalizowana? Jeśli to się skompiluje to zawsze zostanie wywołana metoda z klasy B, bez wzlędu na to czym jest a.
No nie zawsze zostanie wywołana metoda z klasy B, np od B pochodzi C zaś w C ma nadpisaną doSomething2() zaś to a stworzone jako new C();.

1 użytkowników online, w tym zalogowanych: 0, gości: 1