Interfejs lub klasa dziedziczona jako typ obiektu a dostęp do metod

0

Załóżmy,że mam interfejs Loggable, którego zaimplementowałem w pewnej klasie Kwadrat, a ta z kolei była dziedziczona po abstrakcyjnej klasie Figura, czyli w skrócie w nagłówku:

public class Kwadrat extends Figura implements Loggable

Na końcu próbuję sobie utworzyć obiekt, aby móc sobie wywołać takie czy inne metody.

Wiem już, że kiedy definicja wygląda następująco:

Loggable f1 = new Kwadrat(x,y,dl_boku);

to mogę korzystać właściwie tylko z tych funkcji, których definicje umieściłem z interfejsie,

kiedy z kolei jest to

Figura f2 = new Kwadrat(x,y,dl_boku);

to mogę korzystać tylko z funkcji, które znalazły się w klasie Kwadrat, ale z tych co w Interfejsie już nie.
A dzięki zapisowi

Kwadrat f3 = new Kwadrat(x,y,dl_boku);

w końcu mogę korzystać ze wszystkich metod.

Pytanie brzmi: po co są te dwie powyższe wersje? Bo w jednym z egzaminacyjnych pytań znalazło się pytanie, czy to by zadziałało. Skoro jest to działające, to w jakich przypadkach, no bo teraz wydaje mi się to bezsensowne.
I jeszcze dla upewnienia: przykładowe

Figura f = new Figura();

nie dałoby się w ogóle utworzyć ze względu na to że klasa jest abstrakcyjna, co oznacza że się jej obiektów nie tworzy, a istnieje wyłącznie po to żeby sobie po niej dziedziczyć?

0

Nie do końca rozumiem problem. Które przykłady miałyby zadziałać, a które są bezsensowne? Intuicja podpowiada mi, że chodzi Ci o polimorfizm i to co się za tym kryje, że to on jest odpowiedzią na Twoje pytanie, ale nie mam pewności, czy dobrze Cię rozumiem. Może spróbuj jeszcze raz w inny sposób zadać to pytanie?

Co do ostatniego, to tak, klasa abstrakcyjna służy do tego żeby po niej dziedziczyć a nie tworzyć jej egzemplarze. Bo tworząc konkretny obiekt klasy abstrakcyjnej Figura, to...no właśnie jaką właśnie figurę utworzono? Nie masz pojęcia, natomiast tworząc kwadrat już wiesz że mowa o kwadracie. Natomiast klasa Figura ma pewne cechy wspólne dla Kwadratu, Prostokąta, Okręgu, itd. a skoro to cechy wspólne to wpisuje się je do klasy nadrzędnej i dziedziczy po niej, aby nie powielać kodu. To tak mniej więcej.

1

po co są te dwie powyższe wersje? Bo w jednym z egzaminacyjnych pytań znalazło się pytanie, czy to by zadziałało. Skoro jest to działające, to w jakich przypadkach, no bo teraz wydaje mi się to bezsensowne.

Żartujesz? Jak to po co? Chodzi o to żeby metody do których przekazujesz obiekty mogły działać z obiektami różnych typów przejawiających pewne zachowania. Załóżmy że masz interfejs Comparable który oznacza że obiekty takiej klasy można ze sobą porównywać. Teraz piszemy metodę sort() która przyjmuje jako argument listę obieków Comparable. Co się stało? Metoda sort() działa dla KAŻDEGO typu implementującego Comparable. Więc możesz zrobić kilka zupełnie odrębnych hierarchii klas które można będzie sortować tą jedną metodą!
Zresztą patrz na to też tak, że często obiekt jest dość skomplikowany i chcielibyśmy udostępnić pewne "widoki" tego obiektu. Na przykład LinkedList<T> można używać zarówno jako List<T> jak i Queue<T>.
Jakie są inne plusy używania obiektów przez pryzmat interfejsu? Można łatwo podmieniać obiekty! Jakbyś miał w klasie wszędzie napisane LinkedList to zmiana na ArrayList byłaby bardzo bolesna i wymagałaby miliona zmian. Jak masz List to zmieniasz jedną linijkę.

nie dałoby się w ogóle utworzyć ze względu na to że klasa jest abstrakcyjna, co oznacza że się jej obiektów nie tworzy, a istnieje wyłącznie po to żeby sobie po niej dziedziczyć?

Zasadniczo tak. Chodzi o to żeby nie powielać identycznego kodu dla różnych klas (bo kopiowanie kodu to BARDZO zła praktyka). Jeśli jakiś kod ci się powtarza to MUSISZ zastosować dziedziczenie albo delegację.

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