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

Interfejs jako kontrakt

VPS Starter Arubacloud
0 głosów
615 wizyt
pytanie zadane 15 grudnia 2018 w Java przez itcloud Gaduła (3,380 p.)
edycja 15 grudnia 2018 przez itcloud
Mówi się, ze programista opiera się na interfejsie pisząc aplikację, bo tak jest łatwiej, bo inny człowiek z zespołu może zająć się konkretną implementacją, a Ty masz wiedzieć tylko, że ktoś ją wykona blablabla.

Nie rozumiem tego do końca, bo żeby móc przetestować tę aplikację nie mogę sobie pisać tylko że jest jakaś tam metoda i ona ma zwracać listę stringów, bo program po odpaleniu nie wykona czegoś tam, bo nie ma implementacji? Gubię się szczerze mówiąc.

np.

jesli stosuje interfejsy jako typy a po prawej stronie klasę:

Collection<String> costam = ArrayList<>();

to rozumiem że mogę podczas gdy to costam ma być argumentem innej funkcji, tak naprawdę zmieniać implementację, np. z ArrayList na HastSet itd. Ale gdzie tu ten wymóg używania wszystkich nazw metod z interfejsu? Kursy mówią o tym, że jak implementujesz interfejs musisz zrobić przepis, dać logikę, implementację wszystkich metod które się w nim znajdują.

A ja jeśli tworzę kolejne funkcje które mają argument jako wyżej wskazany interfejs np.

void print(Collection<string> costam){   }

to tak jak pisałem rozumiem, że wewnątrz tej metody mogę korzystać z różnych implementacji, ale to nie znaczy że musże w tych implementacjach wykorzystać wszystkie możliwe metody, które są wypisane w interfejsie jako wstępne deklaracje?

1 odpowiedź

+1 głos
odpowiedź 15 grudnia 2018 przez Aisekai Nałogowiec (42,190 p.)
wybrane 15 grudnia 2018 przez itcloud
 
Najlepsza

Posługując się interfejsem, sprawiasz że nie obchodzi Cię konkretna implementacja danego zachowania tylko fakt, że jakiś obiekt przejawia dane zachowanie.

Jeżeli dana metoda działa na polu danej klasy, to przed jej wywołaniem musisz mieć utworzony dany obiekt (inaczej dostaniesz NPE). W tym przypadku, najlepiej się posługiwać dependency injection i podczas tworzenia obiektu danej klasy, podać konkretną implementację interfejsu. 

W sytuacji gdy argumentem metody jest obiekt typu interfejsowego (type of an interface) to problem się rozwiązuje w zasadzie sam.

Korzystając z interfejsów, obchodzi Cię jedynie to że dany obiekt przejawia jakieś zachowanie (obiekt implementuje metodę). Dopiero podczas testowania/uruchamiania aplikacji musisz mieć zapewnioną implementację zachowania tworząc konkretny obiekt.

Ale gdzie tu ten wymóg używania wszystkich nazw metod z interfejsu? Kursy mówią o tym, że jak implementujesz interfejs musisz zrobić przepis, dać logikę, implementację wszystkich metod które się w nim znajdują.
 

Wymóg wprowadza kompilator. Jeżeli uważasz, że jakaś klasa powinna zaimplementować dany interfejs, ale nie "powinna" mieć jakiejś metody tzn, że twój interfejs łamie zasadę Single Responsibility.  W sytuacji, gdy masz interfejs ale często implementacje tej metody będą takie same, możesz posłużyć się defaultowymi metodami. 

1
komentarz 15 grudnia 2018 przez miro Pasjonat (23,870 p.)

akaś klasa powinna zaimplementować dany interfejs, ale nie "powinna" mieć jakiejś metody tzn, że twój interfejs łamie zasadę Single Responsibility

Raczej powiedziałbym, że łamie Interface segregation principle, a pochodną tego jest klasa łamiąca Single Respnsibility bo jest zmuszona mieć metody, które nic nie będą robić. 

komentarz 15 grudnia 2018 przez itcloud Gaduła (3,380 p.)

@Aisekai, jeżeli dana metoda działa na polu danej klasy, to przed jej wywołaniem musisz mieć utworzony dany obiekt (inaczej dostaniesz NPE). W tym przypadku, najlepiej się posługiwać dependency injection i podczas tworzenia obiektu danej klasy, podać konkretną implementację interfejsu. 

a możesz to zilustrować przykładem, bo nie wiem czy dobrze rozumiem.

W skrócie, gubię się z tym od strony praktycznej. W tym co wyżej napisałem jako przykład kodu.

1
komentarz 15 grudnia 2018 przez Aisekai Nałogowiec (42,190 p.)

Najprostsze na co wpadłem:

public class Main3 {
    public static class Group {
        Collection<String> students;

        public Group(Collection<String> students) {
            this.students = students;
        }

        public void printStudents() {
            students.forEach(System.out::println);
        }
    }

    public static void main(String[] args){
        String[] students = {"Asia","Kasia","Piotrek","Janek"};
        Group group1 = new Group(Arrays.asList(students));
        group1.printStudents();

        Group group2 = new Group(Set.of(students));
        group2.printStudents();
    }
}

W tym przypadku, jak widzisz nie ma znaczenia czy do konstruktora podam Set czy List, studenci i tak zostaną wypisani. Jako, że wymogiem utworzenia obiektu Group jest podanie w konstruktorze Collections, pozbyłem się sytuacji wywołania metody przed zainicjowaniem pola students. Dodatkowo, stosując DI mogę w bardzo prosty sposób tworzyć obiekty Group z różną implementacją Collection.

Podobne pytania

0 głosów
2 odpowiedzi 232 wizyt
pytanie zadane 24 czerwca 2017 w Java przez ewazdomu Początkujący (320 p.)
0 głosów
3 odpowiedzi 1,623 wizyt
pytanie zadane 10 maja 2015 w Java przez rubesom Obywatel (1,690 p.)
+1 głos
0 odpowiedzi 96 wizyt

92,454 zapytań

141,262 odpowiedzi

319,089 komentarzy

61,854 pasjonatów

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.

Akademia Sekuraka

Akademia Sekuraka 2024 zapewnia dostęp do minimum 15 szkoleń online z bezpieczeństwa IT oraz dostęp także do materiałów z edycji Sekurak Academy z roku 2023!

Przy zakupie możecie skorzystać z kodu: pasja-akademia - użyjcie go w koszyku, a uzyskacie rabat -30% na bilety w wersji "Standard"! Więcej informacji na temat akademii 2024 znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...