Zangetsukun napisał(a):
Jakiś czas temu wpadłem na pomysł że wrócę do programowania na poważnie i za jakiś czas spróbuję wbić się w branżę. Wybrałem Javę. I tutaj do Was pytanie - mógłby ktoś podać przykład (najlepiej na kawałku kodu) gdzie interfejs okaże się rozwiązaniem koniecznym i nie do przeskoczenia przez wykorzystanie polimorfizu klas? Odbijam się jak piłeczka od ściany, może ktoś z Was wyjaśni to w sposób w który ogarnę różnice. Póki co każdy przypadek jaki przychodzi mi do głowy prędzej czy później rozwiązuję klasycznym dziedziczeniem.
Interfejsy służą jako kontrakt pomiędzy klientem obiektu i konkretną implementacją obiektu.
Dziedziczenia powinieneś używać TYLKO jeżeli rzeczywiście używasz poliformizmu, tzn. istnieje jakaś metoda, która jest używana w każdej klasie dziedzicącej, ale zmienia się jej implementacja. Jeżeli używasz dziedziczenia do "wyciągania rzeczy przed nawias" to robisz to źle. Poczytaj o LSP (Liskov Substitution Principle) z SOLID.
Inna sprawa, że Interfejsy można zaimplementować poprzez dziedziczenie (tak się to robi w Pythonie, bo tam nie ma interfejsów), ale klasy abstrakcyjne nie mają wtedy żadnej implementacji, tylko zdefiniowane sygnatury. W Pythonie nie są sprawdzane typy, także robi się tylko dla potrzeb dokumentacji w razie gdyby ktoś chciał dodać nową implementację.
Natomiast w Javie jeżeli podasz do jakiejś metody implementację interfejsu Foo, a ten obiekt oczekuje implementacji interfejsu Bar, to wywali błąd.
Generalnie w większości przypadków: kompozycja >> dziedziczenie. Ja dziedziczenia używam bardzo rzadko, w zasadzie chyba tylko we wzorcu "template method".