Klasa nazwa_obiektu = new Podklasa();

0

Cześć. Będę bardzo wdzięczny za przybliżenie następującej kwestii:

Mamy dwie klasy:

public class Pies {
	public void f(){
	}
}

public class Lampo extends Pies {
	public int waga = 30;
	public void f(){
		System.out.println(waga);
	}
}

oraz metode main:

	public static void main(String[] args) {
		Pies lampo = new Lampo();
		System.out.println(lampo.getClass());
		lampo.f();
		System.out.println(lampo.waga); // wyskoczy blad: 
	}
}	

 

metoda get.Class() pokazuje, ze lampo to obiekt typu Lampo.
Dlaczego wiec nie moge korzystac z jego pola, a moge korzystac z jego metody(ktora
wykorzystuje jego pole)? Czytalem cos, ze niby ten obiekt ma typ Pies a stan
aktualny Lampo, czy jakos podobnie... ale czy ktos moglby powiedziec, co tam sie
naprawde dzieje? Dlaczego mam dostep do metod nadpisywanych, ktore wykorzystuja
pola podklasy, do ktorych normalnie nie mam dostepu (przez lampo.waga)? A jednoczesnie,
dlaczego gdy usune metode f z klasy Pies, rowniez nie bede mogl wywolac lampo.f();?

0

Bo pole nie jest public :> A metoda jest.

0

ponieważ tutaj : Pies lampo = new Lampo();

robisz rzutowanie w górę. Przy rzutowaniu w górę klasa pies posiada metodę f() natomiast nie posiada pola waga...

To co musisz zrobić to rzutowanie w dół czyli: System.out.println(((Lampo)lampo).waga);

poczytaj o polimorfiźmie :)

0

@losowa nazwa
Heh, nie no pole też ma oczywiscie byc public(u mnie w eclipsie jest tak w domysle) sorry, juz to edytuje. Problem zostaje.

@remigio
Dzieki, brzmi sensowanie. Ale jezeli do mojej klasy Pies dopisze pole int waga; (z wartoscia domyslna) to choc faktycznie bede mogl odwolac sie do lampo.waga to wyswieli ona wartosc 0 (czyli wartosc z podklasy zostanie podczas rzutowania zgubiona). Funkcja przy rzutowaniu przechodzi bez naruszenia. No ale ok, poczytam :)

1

To proste. Wykorzystujesz obiekt Lampo jako obiekt Pies. To jest tak jakbyś nagle zapomniał że to jest Lampo i wiedział tylko ze to jest pies. Nie możesz więc odwołać się do jakiejś szczególnej cechy którą posiada jedynie Lampo. Po co tak w ogóle robić? Wyobraźmy sobie że masz 100 rodzajów psów. Chcielibyśmy teraz wykonywać na tych psach pewne operacje (karmienie, wyprowadzanie etc). Czynność jest taka sama, ale jej implementacja moze być różna (bo jeden pies je X a drugi Y). Tak więc tworzymy sobie pewna klase bazową/interfejs Pies który posiada te czynności, a potem tworzymy sobie odpowiednie implementacje w klasach dziedziczacych. Teraz chcielibyśmy jakoś te Psy przechować. Wszelkie kontenery i tablice wymagają obiektów zgodnego typu, więc nie da rady wepchnąć do tablicy dwóch różnych psów. Ale da sie je tam wepchnąć jako Psy. Java daje możliwość wywolań polimorficznych -> mimo że w tablicy masz obiekt Pies to wywolując metodę nakarm() wywołasz metodę z dobrej klasy.

Rzutowanie w drugą stronę to terroryzm i z reguły świadczy o tym że coś jest źle zaprojektowane.

0

Jasne, ale tym samym rozumowaniem: kazdy pies ma jakas wage. W klasie Pies tworze wiec pole waga. Ale ze rozne psy maja rozne wagi, to wartosc tej wagi zostawiam odpowiednim polom waga w podklasach: owczarek, terrier, itp. Teraz wrzucam troche roznakich psow do kontenera (brr)np. tablicy tab i chcialbym kazdemu z nich powiekszyc wage o 1. Ale nie moge zrobic tab[i].waga+=1.
Rozumiem, ze to moge zrobic z wykorzystaniem metod czy konstruktorow, ale dlaczego nie moge rzutowac w gore pol? To by stwarzalo jakies problemy czy bledy? No chyba ze tak, bo tak, i rzutowac w gore moge metody, a pola nie i juz.
W kazdym razie dzieki wielkie za odpowiedz

1

Nie mozesz tego zrobic, poniewaz w przeciwienstwie do metod, pola klas w javie nie sa wirtualizowane - nie podlegaja polimorfizmowi.

Robi sie to inaczej, nie przeslania sie pol, tylko ustala inna ich wartosc np. w konstruktorze konkretnej podklasy. Wtedy juz takie tab[i].waga += 1; zadziala tak jak powinno.

//sory za brak polskich znakow, ale cos zdalny pulpit w xp marnie chodzi ;/

0
chlopekchlopek napisał(a)

Rozumiem, ze to moge zrobic z wykorzystaniem metod czy konstruktorow, ale dlaczego nie moge rzutowac w gore pol?

W jakim sensie nie możesz? Pola klasy bazowej (z wyjątkiem tych prywatnych) są dostępne w klasach pochodnych.

Tak w ogóle, to całość koncepcyjnie leży i kwiczy. Dlaczego niby Lampo jest w ogóle klasą? To może być co najwyżej obiekt klasy Pies z ustawionymi (w konstruktorze) imieniem, wagą, rasą, itd.

0

Nie moge rzutowac w gore w tym sensie, ze majac

klasa Pies, z polem int waga;

oraz

podklasa Lampo, z polem int waga = 30;

to przy wywolaniu:

Pies lampo = new Lampo();

lampo.waga bedzie mialo wartosc 0, a nie 30 (czyli wartosc wagi
nie zostanie przeniesiona). Wszystko ok, byku_guzio wyzej napisal
czemu tak nie moze byc.

No ta sa przykladowe klasy, chodzi tylko o chec zrozumienia
mechanizmow :)

0

@chlopekchlopek nie nie nie. Nie myl WARTOŚCI pola od pola jako takiego!
Wartość pól MOZESZ DOWOLNIE USTALAĆ! MYŚL! Przecież mozesz mieć 100 różnych obiektów Pies, każdy z inną wagą! Jesli tworzysz podklasę, to musi to z czegoś wynikać. Na przykład z tego ze chcesz dodać jakieś pole albo z tego ze chcesz zmienić implementację metody.

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.