Tablica polimorficzna - nie działa przeciążenie metody

0

Witam pytanie dla niektórych banalne ale ja nie mam zielonego pojęcia dlaczego w tym kodzie nie wykonuje mi się metoda strasz z klasy potwór?

public class PotworTester {
public static void main(String[] args) {
	Potwor[] ptw = new Potwor[3];
	ptw[0] = new Wampir();
	ptw[1] = new Smok();
	ptw[2] = new Potwor();
	for (int x = 0; x < 3; x++) {
			ptw[x].strasz(x);
		}
	}
}

class Potwor {
	boolean strasz(int z) { // pierwotna metoda
		System.out.println("auuuuuu");
		return true;
		}
}

class Wampir extends Potwor { // przeciążona metoda
	boolean strasz(byte b) {
		System.out.println("można gryza");
		return true;
		}
}

class Smok extends Potwor {
	boolean strasz(int stopien) { // przesłonięta metoda
			System.out.println("zioń ogniem");
			return true;
		}
} 

W konsoli ma mi się wyświetlić
można gryza?
zioń ogniem
auuuu

0

W sumie to nie wiem co Ci nie działa:
http://ideone.com/777K3Q
Sprawdziłem, działa.

0

W konsoli ma mi się wyświetlić:
można gryza?
zioń ogniem
auuuu

a wyświetla się:
auuuuuu
zioń ogniem
auuuuuu

1

Być może różnicą są inne typy parametrów funkcji?

3

Java nie wspiera kontrawariancji dla typów argumentów w metodach, a wspierania kowariancji dla argumentów metod (czyli niejako tego co chciałeś zrobić) to nie ma prawie w żadnym jezyku!
Zastanów sie co zrobiłeś -> w klasie podchodnej dałeś zawężony typ argumentu metody! A zgodnie z Zasadą Podstawiania Liskov obiekt klasy pochodnej moze być użyty zawsze w miejscu obiektu klasy bazowej.

Czyli twój Wampir musi "pasować" wszędzie gdzie pasuje Potwor. Ale u ciebie chciałbyś żeby metoda strasz() dla Wampira przyjmowała inny argument! A to nie ma sensu. Nawet gdybyśmy założyli ze byte jest pochodną int (bo każdy byte może być użyty jako int) to nadal nie ma to sensu, bo co się stanie jeśli wezmę Wampira, potraktuje jako potwora i przekaże argument nie będący byte tylko czymś większym?

Niektóre języki wspierają kontrawariancje typów argumentów metod, więc klasa pochodna może mieć argument bardziej ogólny. Ma to sens bo wszystko co wyślemy do klasy bazowej będzie pasować też do pochodnej, skoro klasa pochodna oczekuje bardziej ogólnego argumentu (np. oczekuje dowolnego Number podczas gdy klasa bazowa przyjmuje tylko Integery).
Java takiego mechanizmu nie wspiera, więc typy argumentów muszą pozostać niezmienione.

Java wspiera jedynie kowariancje typów zwracanych z metod, więc metoda pochodna moze zwrócić typ bardziej szczegółowy. Ma to sens, bo skoro metoda bazowa zwraca Number a metoda pochodna zwróci Integer, to nadal nie ma problemu bo każdy Integer to Number.

0

@Shalom czy można to w skrócie powiedzieć że w dziedziczeniu nie można przeciążać metod tylko je przysłaniać?

0

Nie można bo jeden mechanizm z drugiem nie ma nic wspólnego. Poza tym są języki gdzie jest możliwa kowariancja/kontrawariancja.

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