typ zmiennej a tym obiektu

0

Część,
mam problem z dokładnym zrozumieniem jednego tematu. Załóżmy, że mam 2 klasy Parent i Child, która dziedziczy po Parent. Jako ze w javie mamy upcasting, bez problemu mogę przypisać obiekt typu Child do zmiennej typu Parent.
Parent c = new Child();
wiem, ze zmienna c nie przechowuje rzeczywistego obiektu a tylko referencje do niego. Załóżmy, ze klasa Child ma metode doSomething() ktorej nie ma w klasie Parent. Wiem, że w sytuacji w której obiekt Child jest powiązany z obiektem typu Parent nie mogę z tej metody skorzystać, ale właściwie dlaczego, skoro mimo wszystko moja zmienna ma referncje do Child, wiec obiekt który mamy w pamięci powinien mieć taka metodę?
Jeżeli zrobię:
Child c2 = (Child) c; to będę mógł wywołać metodę doSomething(), z czego wnoszę, ze obiekt który stworzyliśmy na samym początku cały czas te metoda miał tylko java "ukryła" ja przede mna? Czy byłby ktoś w stanie wytłumaczyć mi, jak dokładnie dochodzi do tego "ukrycia"?

4

W krótkich słowach - bo Java jest statycznie typowana a nie dynamicznie.
Wyobraź sobie co by było gdybyś jednak w tej zmiennej c miał obiekt klasy Parent. Wywaliłoby się jak pierwszy lepszy Python czy JS, bo nie znalazłoby odpowiedniej metody podczas działania programu

Statyczne typowanie oznacza że jest sprawdzany typ zmiennej do której przypisujesz.
Dynamiczne typowanie oznacza że wszystkie zmienne mają typ Object a to czy można wywołać metodę czy nie można jest ustalane w trakcie działania programu

4
  1. tak, referencja to typu niższego "ukrywa", że rzeczywistości jest wyższy
  2. Już na starcie - biorąc po uwagę nazwy klas - myślisz w zły sposób o dziedziczeniu. Pachnie złymi poradnikami itd.
    relacja pomiędzy Child a Parent nie jest "is", ale jest "has", kompozycja.
    Dziedziczenie jest relacją "is", np Peach is Fruit
3

@roland_13 jw, statyczne vs dynamiczne typowanie. Chcesz zeby kompilator powiedział ci że możesz mieć błąd, czy żeby wywaliło się dopiero w runtime? Przykład:

Parent p = null;
if (new Random().nextBoolean()){
  p = new Parent();
}else{
  p = new Child();
}
p.doSomething();

I co teraz? Na poziomie kodu NIE DA SIĘ stwierdzić czy p będzie miało referencje do Parent czy Child

0

Dzięki wielkie wszystkim za pomoc, faktycznie, w ogolę nie pomyślałem o typowaniu. Mam jeszcze jedno pytanie, trochę powiązane z tym problem. Wiem, że w javie mamy runtime polymorphism i compiletime. Runtime jest powiązany z overriding a compiletime z overloadingiem. Wszystko spoko, tylko, zakładając, że jakaś klasa ma 4 metody putData() każda przyjmuje inny typ danych. Z tego co rozumiem, to która metoda zostanie użyta rozwiązywane jest podczas kompilacji programu, ale przeciez zawsze w runtime mogę zmienić linie kody gdzie wywołana est metoda putData() i np zamiast int podać Stringa i kod się nie wykrzaczy co by wskazywało na to, że podczas runtime tez dochodzi do rozwiązania której metody należny użyć. Czy coś mi tutaj umyka?

1

w runtime mogę zmienić linie kody gdzie wywołana est metoda putData()

Jak chcesz to zmienić w runtime? Chcesz podmieć bajtkod? :D Dostaniesz ClassCastException w takiej sytuacji i jak najbardziej się wysypie

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