Interfejsy, kl abstrakcyjne - po co właściwie je stosować?

1

Witam
Na poczatku powiem, że nie wiedziałem czy zalozyc wątek w newbie czy tutaj, ale zdecydowalem o javie ze wzgledu na przyklad ktory podam zaraz.

Dzis staje przed wami z takim właśnie problemem. Do czego służa nam interfejsy i klasy abstrakcyjne w javie? wiem na czym to polega mniej-wiecej, ze klasy abstrakcyjne maja metody bez "ciała" i trzeba je nadpisac itd. Chodzi mi jednak o samo sedno, kiedy wy - jako bardziej zaawansowani je stosujecie? W jakich wypadkach trzeba pisac interfejs a w jakich nie? kiedy interfejs a kiedy klase abstrakcyjną, a kiedy w ogole zwykla klase?

Obecnie się ucze i w moich projektach jeszcze nigdy nie pisalem klasy abstrakcyjnej badz interfejsu, nie wpadłem na myśl że akurat gdzieś tam powinienem ją/go zrobić. Moze to byc spowodowane tym ze to małe programy, nie wielkie kolosy i może dopiero wtedy staje sie to przydatne? Może to sie zyskuje z doświadczeniem? (pytanie jak na to wpaść z doswiadczenia skoro nigdy sie tego nie używało.. ;) )
Chciałbym wiedziec kiedy to stosować :)

Przykład o którym wspominałem na poczatku: mamy interfejs ActionListener
Moje pytanie brzmi: dlaczego to akurat interfejs a nie zwykły obiekt? przeciez możnaby wykonywac operacje na obiekcie i tak z dystansem na to patrzac mogloby byc wygodniej, nie trzeba byloby importowac, napisywac metod, wszystko opieraloby sie o zwykłą klase.

Pytanie moje dlaczego tak zrobili a nie inaczej, czemu akurat interfejs a nie kl. abstr. albo zwykła klasa?

pozdrawiam i prosze o wsparcie w temacie :D

0

Klasy Abstrakcyjne (trochę inny język, ale idea ta sama)

0

Wybrałeś zły przykład, interfejs ActionListener ma tylko jedną metodę i ciało tej metody musi napisać programista - tylko on wie jak ma wyglądać obsługa zdarzenia. Zmiana na klasę lub klasę abstrakcyjna nie dałaby żadnych korzyści programiście. Dla interfejsów, które mają więcej metod (np. MouseListener) istnieje klasa abstrakcyjna z pustymi metodami. Programista może się ograniczyć do nadpisania tylko potrzebnych mu metod.

0

Interfejsy wydają się głupie:
Po co definiować, jakie metody będzie miała klasa? O ile wygodniej napisać samą klasę i po prostu z niej korzystać?
W praktyce robi się jednak trochę ciekawiej.
Wyobraź sobie, że masz interfejs ObslugaBazyDanych, a w nim metody "dodajUzytkownika(Uzytkownik) i usunUzytkownik(Uzytkownik).
Teraz piszesz sobie klasy: ObslugaBazyDanychWPliku implements ObslugaBazyDanych, ObslugaBazySQL implements ObslugaBazyDanych, ObslugaObiektowejBazyDanych implements ObslugaBazyDanych.
Po pierwsze:
Jak ktoś kiedyś będzie chciał napisać kolejną wersję obsługi z bazą danych, to od razu narzucisz mu standard, który musi spełnić.
Po drugie, możesz w dowolnym miejscu w kodzie zrobić:
ObslugaBazyDanych obd = new <któraś obsługa>();
obd.dodajUzytkownika(...);
Niezależnie od tego, którą obsługę wybierzesz (np. w jakiejś fabryce lub zależnie od parametrów użytkownika), to kompilator spokojnie to przepuści i będzie to śmigać.
Jest jeszcze weselej, jak dzielisz kod pomiędzy serwer i klienta (EJB, RMI). Wtedy obie strony muszą wiedzieć, jakie metody można wykonać, ale tylko jedna (serwer) ma ciało tych metod.

0

Ja to rozumiem w ten sposób ze nie ma sensu pisać nowych klas jak można wykorzystać interfejsy, ktore już istnieją. Do tego w Javie mozna dziedziczyć po jednej klasie a interfejsów możesz zaimplementowac dowolną liczbę wiec zamiast 7 klas można zrobic jedna implementujaca 6 interfejsów. Mam nadzieje ze moj tok rozumowania jest dobry:)

Napisane z HTC.

0

@PanKalmar nie, nie jest. To jest bardzo zła praktyka takie wpychanie interfejsów na pałę. Klasy "człowie-orkiestra" są złe, niemożliwe w utrzymaniu i wskazują na błędy projektowe. Klasy powinny być małe i zgodne z Zasadą Jednej Odpowiedzialności.
Idea interfejsów jest taka, żeby można było użyć nowej implementacji w starym kodzie. Tzn w kodzie który powstał przed tą implementacją. Poza tym ułatwia to też składanie implementacji z "klocków" poprzez delegację.

0

Wybrałeś zły przykład, interfejs ActionListener ma tylko jedną metodę i ciało tej metody musi napisać programista

A jaki może być dobry przykład? Taki który mi pokaże, że warto było użyć interfejs a nie zwykly obiekt?

Powoli zaczynam rozumieć, chodzi o to, że interfejs jest pewnym sprawdzonym schematem, który jest możliwy do wykorzystania dla wielu przypadków. Stąd też wyciągam wniosek, że interfejsy i klasy abstrakcyjne zaczyna się używać dopiero w większych projektach - bo w mniejszych programach nawet na siłe nie ma gdzie tego wcisnąć. Mam racje?

Bo o ile przykłady typu: mamy kota psa i mysz, maja podobne cechy tj. chodzenie, ilosc łap itp. i stworzymy superklase abstrakcyjną Zwierze - jest przykładem do pojęcia w zupełności - jednak w przypadku kiedy stajemy przed napisaniem programu gdzie juz nie chodzi o psy i myszy, a o zdecydowanie bardziej "informatyczne" tematy, wszystko zaczyna sie "capciać".

Wiec pytanie - czy poukładanie tego w głowie przychodzi z czasem? bo skoro obecnie nie używam - przez wielkość projektów bądz tez po prostu przez zbyt małą wiedzę - dlaczego miałbym kiedyś używać skoro wczesniej w ogole z tym nie praktykowalem?

dzieki za tyle odpowiedzi ;)

#edit

Idea interfejsów jest taka, żeby można było użyć nowej implementacji w starym kodzie. Tzn w kodzie który powstał przed tą implementacją. Poza tym ułatwia to też składanie implementacji z "klocków" poprzez delegację.

Gdybys mogl troche rozszerzyć myśl byłbym wdzięczny, co masz na myśli mówiąc o używaniu nowej implementacji w starym kodzie? (jeśli ktoś wyciaga projekt z przed 5 lat i ma tam interfejs X to może po latach napisać nową klase używajac tego interfejsu i implementując metody na nowy, bardziej nowoczesny czy też mądrzejszy sposób - bo a nóż pojawiły się nowe technologie --- o to tu chodzi?)

0
azalut napisał(a):

dlaczego miałbym kiedyś używać skoro wczesniej w ogole z tym nie praktykowalem?

bo kolega z teamu 2 tygodnie wcześniej napisze kontroler który będzie zarządzał obiektami implementującymi wymyślony przez niego interfejs a ty będziesz musiał te obiekty dorobić. Dlatego będziesz ich używał mimo braku wcześniejszej praktyki :)

0

tylko chodzi mi raczej o TWORZENIE przeze mnie wszystkiego od podstaw, aniżeli kontynuowanie czyichś dzieł.
Inaczej mówiąc chodzi mi o to, że ja bede nie tym który dorabia obiekty, a tym kolegą z teamu. Ja to napoczne - i czy bede wiedział, że należało zrobić interfejs? bo skoro nigdy nie tworzylem ich to zapewne nie wpadne na to że akurat to bedzie dobre rozwiązanie

Podaje tylko przykład wyżej, bo obecnie w żadnym teamie nie jestem, jestem jeszcze przez jakiś czas młodym niedoświadczonym samoukiem ;)

0

Ćwiczenie dla ciebie:

  • wymyśl sobie jakiś format wyjściowy pliku, najlepiej mega skomplikowany.
  • wymyśl sobie 3 formaty wejściowe
    Spróbuj napisać program konwertujący te 3 formaty wejściowe na format wyjściowy.
    Załóż że przewidujesz pojawienie się nowych typów plików wejściowych do obsłużenia.
    Sensowne rozwiązanie tego problemu wyglądałoby tak że zrobiłbyś jeden konwerter do postaci wyjściowej a następnie hierarchię klas o wspólnym zestawie metod, które będą "źródłem" dla konwertera. W efekcie konwerter będzie uniwersalny dla dowolnego formatu wejściowego o ile obiekt obsługujący wczytanie danych będzie udostepniał odpowiednie metody.

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