• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Dlaczego przy tworzeniu nowego obiektu, z reguły deklarujemy referencję z typu nadklasy?

Aruba Cloud VPS - 50% taniej przez 3 miesiące!
0 głosów
562 wizyt
pytanie zadane 9 listopada 2016 w Java przez pulpet112 Użytkownik (760 p.)

Witam! 

Być może w temacie niezbyt jasno się wyraziłem dlatego może jakiś przykład:

1. Chcemy stworzyć obiekt typu LinkedList. W literaturze, najczęściej spotykany zapis tego procesu to:

List<String> list = new LinkedList<String>();

2. Chcemy stworzyć obiekt typu HashSet. W literaturze spotkamy to:

Set<Integer, String> list = new HashSet<Integer, String>();

Teraz jest już chyba jasne o co chodzi. Dlaczego referencja jest deklarowana z nadklasy obiektu który tworzymy? Czy odnosimy z tego tytułu jakąś korzyść? Bo moim zdaniem przysparza to raczej problemów. Jak wiadomo kompilator nie patrzy na obiekt tylko na referencje. W związku z tym gdy w nadklasie nie będzie metody którą wywołujemy dostaniemy ComplieError. Skoro tak to logika podpowiada żeby deklarować jak "najniższe" referencje (najbliższe albo po prostu te same względem obiektu który tworzymy).

Dlaczego więc tego nie robimy i dlaczego warto deklarować typ postawiony wyżej w hierarchii dziedziczenia?

Dziękuję :)

komentarz 9 listopada 2016 przez mbabane Szeryf (79,260 p.)
List czy Set nie jest nadklasa tylko interfejsem
komentarz 9 listopada 2016 przez pulpet112 Użytkownik (760 p.)
jej....no fajnie, przeciez kazdy wie o co chodzi... Bardziej byłbym wdzięczny za pomoc polegającą na odpowiedzeniu na pytanie a nie czepianiu się słówka, który w kontekscie w jakim go użyłem i tak jest zrozumialy dla kazdego...
komentarz 9 listopada 2016 przez mbabane Szeryf (79,260 p.)
Dlatego uzylem komentarza, a nie pelnej odpowiedzi, by nie zwracac az tak na to uwagi, po to zostaly stworzone komentarze. Po za tym daje Ci to juz pewien punkt zaczepienia by porownac sobie stosowanie interfejsow i dziedziczenia w celu znalezienia odpowiedzi na postawione pytanie.

Jednym z plusow jest uniwersalnosc kodu, mozna bezproblemu uzywac ArrayList, czy innego cuda, np. gdybys oddal klase komus, dalbys tej osobie mozliwosc wyboru, ktorej implementacji ma uzyc bo np. jedna implementacja jest mniej wydajna, a inna wygodniejsza w obsludze, a jeszcze inna zapewnia sortowanie elementow po dodaniu.

Moze tez to posluzyc sprawdzeniu czy dana implementacja klasy rzeczywiscie implementuje taki interfejs.

Byc moze chodzi tez o czytelnosc kodu - aha ta zmienna jest lista ok, a wiec mozna z nia zrobic to, to i tamto - niekoniecznie trzeba znac wszystkie implementacje, trzeba przede wszystkim znac ogolna zasade.

3 odpowiedzi

+1 głos
odpowiedź 9 listopada 2016 przez ribeiro Stary wyjadacz (11,440 p.)

Daje nam to możliwość przypisania do zmiennej dowolnej podklasy. Można sobie wyobrazić na przykład:

List<Object> nieWiemKtoraImplementacjaLepsza;

if(lepszaJestTablica) {
    nieWiemKtoraImplementacjaLepsza = new ArrayList<Object>();
} else {
    nieWiemKtoraImplementacjaLepsza = new LinkedList<Object>();
}

 

1
komentarz 9 listopada 2016 przez pulpet112 Użytkownik (760 p.)

uuuu faktyczniesurprise  To jest świetna zaleta niewątpliwie laugh Są jeszcze jakieś inne, równie lub mniej ciekawe?

A co w takim razie z problemem kompilatora który opisałem? Czy w praktyce jest to na tyle mało istotny problem, że warto się na niego godzić?

+1 głos
odpowiedź 9 listopada 2016 przez ReksetoDev Gaduła (4,530 p.)

Powiedzmy ze robisz Polaczenie z jakas baza danych robisz interfejs DataSource w nim metody get bla bla.. i implementacje DataSourceFlat DataSourceSQL 

DataSource src;

if(config.typedatabase.equals(sql))
{
DataSource src = new DataSourceSQL
}

 

komentarz 9 listopada 2016 przez pulpet112 Użytkownik (760 p.)

no dobra...niby wszystko spoko. Ale tak naprawdę....taki przykład nie tłumaczy dlaczego warto dawać referencje z klasy wyższej (lub interfejsu!! smiley )  tworząc obiekt typu podklasowego. Np ten przykład powyżej da się przecież zastąpić czymś takim:

 
if(config.typedatabase.equals(sql))
{
DataSourceSQL src = new DataSourceSQL
}
else {
DataaSourceDefault src = new DataSourceDefault
}

i tak dalej... nie ma przecież potrzeby deklarować DataSource src; przed ifem.

To samo tyczy się wcześniejszego przykładu. Jak na moje rozumowanie nie ma nic złego aby zastąpić kod @ribeiro:


List<Object> nieWiemKtoraImplementacjaLepsza;
 
if(lepszaJestTablica) {
    nieWiemKtoraImplementacjaLepsza = new ArrayList<Object>();
} else {
    nieWiemKtoraImplementacjaLepsza = new LinkedList<Object>();
}

takim kodem:


if(lepszaJestTablica) {
    ArrayList<Object> nieWiemKtoraImplementacjaLepsza = new ArrayList<Object>();
} else {
   LinkedList<Object>  nieWiemKtoraImplementacjaLepsza = new LinkedList<Object>();
}

Przecież tylko zadelarowanie że jakaś struktura danych będzie istnieć zupełnie nic nam nie daje. Nie możemy z nią nic zrobić dopóki jej nie zainicjujemy.

A może coś daje ale o tym nie wiem??

komentarz 9 listopada 2016 przez Javowiec Pasjonat (21,560 p.)

Nie panie, tak tego nie zastąpisz, bo przy użyciu tego poza ifem dostaniesz błąd kompilatora:

Cannot resolve symbol 'blablabla'.

komentarz 9 listopada 2016 przez pulpet112 Użytkownik (760 p.)

ahhh no jasne, teraz czaje!!!!! Dziękuję ci bardzo wink

+1 głos
odpowiedź 9 listopada 2016 przez Javowiec Pasjonat (21,560 p.)

W Javie programujemy obiektowo, a założeniami takiego programowania są:

  • Hermetyzacja,
  • Dziedziczenie,
  • Abstrakcja
  • Polimorfizm.

To o czym piszesz, to użycie polimorfizmu.

Można o tym poczytać na wielu stronach np. tu.

komentarz 9 listopada 2016 przez pulpet112 Użytkownik (760 p.)
wiem czym jest polimorfizm i że to o czym pisze to przykład polimorfizmu. Jednak moje pytanie nie miało na celu dowiedziec się z jakiego założenia korzystam deklarujac w ten sposób daną strukturę danych, tylko dowiedziec się po co robi się to w tym konkretnym przypadku. Po co stosuje sie polimorfizm tez wiem ale nie widzę aby w tym przypadku on coś znacząco ułatwiał
komentarz 9 listopada 2016 przez Javowiec Pasjonat (21,560 p.)
W małych aplikacjach to nie ma większego znaczenia. Bardziej ma to znaczenie przy pracy w ogromnych aplikacjach.

Czysty kod zaleca używanie polimorfizmu i takiego deklarowania zmiennych. Odnoszenie się do metod poprzez interfejs, a implementację wybierać podczas działania programu w sposób dynamiczny.

Możesz pisać jak Ci się podoba.
komentarz 9 listopada 2016 przez Javowiec Pasjonat (21,560 p.)

Interfejsy mają za zadanie deklarowanie czystego, abstrakcyjnego zachowania klas, które będą go implementowały.

Gdy wywołujesz:

list.add(entity);

nie obchodzi Cię implementacja (w jaki sposób to zostanie zrobione), tylko efekt końcowy (do listy zostanie dodany nowy obiekt).

W związku z tym, deklarujemy zmienne poprzez podawanie typu interfejsu. Implementacja jest w tym przypadku mniej ważna.

Podobne pytania

+2 głosów
1 odpowiedź 1,375 wizyt
pytanie zadane 1 listopada 2016 w C i C++ przez Arturo332 Początkujący (250 p.)
+1 głos
1 odpowiedź 232 wizyt
pytanie zadane 2 marca 2018 w C i C++ przez Paweł Dymek Bywalec (2,300 p.)
0 głosów
0 odpowiedzi 248 wizyt
pytanie zadane 27 lutego 2018 w Mikrokontrolery przez Paweł Dymek Bywalec (2,300 p.)

93,188 zapytań

142,204 odpowiedzi

322,027 komentarzy

62,515 pasjonatów

Advent of Code 2024

Top 15 użytkowników

  1. 2817p. - dia-Chann
  2. 2769p. - Łukasz Piwowar
  3. 2759p. - Łukasz Eckert
  4. 2704p. - Tomasz Bielak
  5. 2678p. - Łukasz Siedlecki
  6. 2627p. - CC PL
  7. 2485p. - Marcin Putra
  8. 2443p. - rucin93
  9. 2418p. - Michal Drewniak
  10. 2367p. - Adrian Wieprzkowicz
  11. 2317p. - Mikbac
  12. 2156p. - Anonim 3619784
  13. 2127p. - Michał Telesz
  14. 1733p. - rafalszastok
  15. 1628p. - Dominik Łempicki (kapitan)
Szczegóły i pełne wyniki

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj

Wprowadzenie do ITsec, tom 1 Wprowadzenie do ITsec, tom 2

Można już zamawiać dwa tomy książek o ITsec pt. "Wprowadzenie do bezpieczeństwa IT" - mamy dla Was kod: pasja (użyjcie go w koszyku), dzięki któremu uzyskamy aż 15% zniżki! Dziękujemy ekipie Sekuraka za fajny rabat dla naszej Społeczności!

...