Jestem na etapie uczenia się programowania, w którym czuję, że muszę dowiedzieć się więcej o interfejsach.
Często o nich czytam, ale wygląda na to, że ich nie rozumiem.
Czytałem przykłady: klasa bazowa zwierząt, z interfejsem IAnimal do takich rzeczy jak „Spacer”, „Uruchom”, „GetLegs” itp. - Ale nigdy nad tym nie pracowałem i czułem, że „Hej, powinienem użyć interfejsu tutaj!"
czego mi brakuje? Dlaczego tak trudno mi to pojąć! Jestem po prostu zastraszony faktem, że nigdy nie zdaję sobie sprawy z konkretnej potrzeby - głównie z powodu jakiegoś brakującego aspektu ich zrozumienia! To sprawia, że mam wrażenie, że brakuje mi czegoś na topie, jeśli chodzi o bycie programistą! Jeśli ktoś miałby takie doświadczenie i przełom, byłbym wdzięczny za kilka wskazówek, jak zrozumieć tę koncepcję. Dziękuję Ci.
źródło
Odpowiedzi:
rozwiązuje ten konkretny problem:
masz a, b, c, d 4 różnych typów. w całym kodzie masz coś takiego:
dlaczego nie ma ich wdrożyć IProcessable, a następnie zrobić
skaluje się to znacznie lepiej, jeśli dodasz, powiedzmy, 50 typów klas, które wszystkie robią to samo.
Kolejny konkretny problem:
Czy kiedykolwiek spojrzałeś na System.Linq.Enumerable? Definiuje mnóstwo metod rozszerzenia, które działają na każdym typie, który implementuje IEnumerable. Ponieważ wszystko, co implementuje IEnumerable, w zasadzie mówi „popieram iterację w nieuporządkowanym wzorcu typu foreach”, możesz zdefiniować złożone zachowania (Count, Max, Where, Select, itp.) Dla dowolnego typu enumerable.
źródło
foreach(IMyCompanyWidgetFrobber a in list) a.Frob(widget, context);
Bardzo podoba mi się odpowiedź Jimmy'ego, ale czuję, że muszę coś do niej dodać. Kluczem do wszystkiego jest „zdolny” w IProcess zdolny. Wskazuje na zdolność (lub właściwość, ale oznacza „wewnętrzną jakość”, a nie w sensie właściwości C #) obiektu, który implementuje interfejs. IAnimal prawdopodobnie nie jest dobrym przykładem interfejsu, ale IWalkable może być dobrym interfejsem, jeśli twój system ma wiele rzeczy, które mogą chodzić. Możesz mieć klasy pochodzące od zwierząt, takie jak pies, krowa, ryba, wąż. Pierwsze dwa prawdopodobnie zaimplementują IWalkable, pozostałe dwa nie chodzą, więc nie. Teraz pytasz „dlaczego nie mieć kolejnej nadklasy, WalkingAnimal, z której wywodzą się Pies i Krowa?”. Odpowiedź brzmi, gdy masz coś całkowicie poza drzewem dziedzictwa, które również może chodzić, na przykład robot. Robot zaimplementuje IWalkable, ale prawdopodobnie nie będzie pochodził od Animal. Jeśli chcesz listę rzeczy, które mogą chodzić,
Teraz zastąp IWalkable czymś bardziej programowym, takim jak IPersistable, a analogia stanie się znacznie bliższa temu, co zobaczysz w prawdziwym programie.
źródło
Użyj interfejsów, gdy implementacje tej samej funkcjonalności będą się różnić.
Użyj klasy abstrakcyjnej / podstawowej, jeśli chcesz udostępnić wspólną konkretną implementację.
źródło
is
słowie kluczowym)Pomyśl o interfejsie jak o umowie. To sposób na powiedzenie: „Te klasy powinny przestrzegać tych zasad”.
Tak więc w przykładzie IAnimal można powiedzieć: „MUSZĄ być w stanie wywoływać bieg, spacer itp. Na klasach, które implementują IAnimal”.
Dlaczego to jest przydatne? Możesz zbudować funkcję, która polega na tym, że musisz mieć możliwość wywoływania funkcji Run and Walk, na przykład na obiekcie. Możesz mieć następujące:
... i powtórz to dla wszystkich obiektów, które znasz, mogą biegać i chodzić. Jednak w interfejsie IAnimal możesz zdefiniować funkcję jeden raz w następujący sposób:
Programując w oparciu o interfejs, zasadniczo ufasz klasom, że zrealizują zamiar interfejsu. W naszym przykładzie myśl brzmi: „Nie dbam o to, jak biegają i chodzą, dopóki biegają i chodzą. Mój RunThenWalk będzie ważny, dopóki spełnią tę umowę. Działa doskonale, nie wiedząc o niczym innym klasa."
W tym pokrewnym pytaniu jest również dobra dyskusja .
źródło
Nie martw się tak bardzo. Wielu programistów rzadko będzie musiało napisać interfejs. Często będziesz korzystać z interfejsów dostępnych w ramach .NET , ale jeśli nie poczujesz potrzeby pisania w najbliższym czasie, nie ma w tym nic zaskakującego.
Przykład, który zawsze komuś daję, to jeśli masz klasę żaglówki i klasę żmii. Dziedziczą odpowiednio klasę łodzi i klasę samochodów. Teraz powiedz, że musisz przejść przez wszystkie te obiekty i wywołać ich
Drive()
metodę. Chociaż możesz napisać kod podobny do następującego:O wiele łatwiej byłoby napisać:
źródło
Jimmy ma rację, gdy chcesz być w stanie używać jednej zmiennej dla wielu typów, ale wszystkie te typy implementują tę samą metodę za pomocą deklaracji interfejsu. Następnie możesz nazwać je główną metodą na zmiennej typu interfejs.
Istnieje jednak drugi powód, aby używać interfejsów. Gdy architekt projektu jest inną osobą niż programista implementacji lub istnieje kilka programistów implementacji i jeden kierownik projektu. Osoba odpowiedzialna może napisać całą gamę interfejsów i sprawdzić, czy system współpracuje, a następnie pozostawić programistom wypełnienie interfejsów klasami implementacji. Jest to najlepszy sposób, aby zapewnić, że wiele osób pisze kompatybilne klasy i mogą to robić równolegle.
źródło
Lubię analogię armii.
Sierżant nie dba o to, czy jesteś programistą , muzykiem lub prawnikiem .
Jesteś traktowany jak żołnierz .
Jest to łatwiejsze dla sierżanta nie zajmować się szczegółami konkretnych osób, przy których pracuje z,
traktują wszystkich jak abstrakcjami żołnierz (... i karania ich, gdy nie działają jak te).
Zdolność osób do zachowywania się jak żołnierze nazywa się polimorfizmem.
Interfejsy to konstrukcje oprogramowania, które pomagają osiągnąć polimorfizm.
Potrzeba abstrakcyjnych szczegółów w celu osiągnięcia prostoty jest odpowiedzią na Twoje pytanie.
źródło
Z mojego doświadczenia wynika, że siła napędowa do tworzenia interfejsów nie pojawiła się, dopóki nie zacząłem przeprowadzać testów jednostkowych przy użyciu frameworku. Stało się zupełnie jasne, że korzystanie z interfejsów znacznie ułatwi drwiny (ponieważ ramy zależą od metod wirtualnych). Kiedy zacząłem, zobaczyłem wartość abstrakcji interfejsu mojej klasy od implementacji. Nawet jeśli nie utworzę rzeczywistego interfejsu, staram się teraz uczynić moje metody wirtualnymi (zapewniając niejawny interfejs, który można zastąpić).
Jest wiele innych powodów, dla których odkryłem, że wzmacniam dobrą praktykę refaktoryzacji do interfejsów, ale testowanie / kpowanie z jednostek było tym, co zapewniło początkowy „aha moment” praktycznego doświadczenia.
EDYCJA : Aby to wyjaśnić, przy testowaniu jednostkowym i kpinach zawsze mam dwie implementacje - rzeczywistą, konkretną implementację i alternatywną próbną implementację używaną w testowaniu. Gdy masz dwie implementacje, wartość interfejsu staje się oczywista - radzi sobie z tym pod względem interfejsu, abyś mógł w dowolnym momencie zastąpić implementację. W tym przypadku zastępuję go fałszywym interfejsem. Wiem, że mogę to zrobić bez faktycznego interfejsu, jeśli moja klasa jest poprawnie zbudowana, ale użycie faktycznego interfejsu wzmacnia to i czyni go czystszym (czytelniejszym dla czytelnika). Bez tego impulsu nie sądzę, że doceniłbym wartość interfejsów, ponieważ większość moich klas ma tylko jedną konkretną implementację.
źródło
Niektóre nieprogramowe przykłady, które mogą pomóc ci zobaczyć właściwe zastosowania interfejsów w programowaniu.
Istnieje interfejs między urządzeniami elektrycznymi a siecią elektryczną - jest to zestaw konwencji dotyczących kształtu wtyczek i gniazd oraz napięć / prądów w poprzek nich. Jeśli chcesz wdrożyć nowe urządzenie elektryczne, o ile wtyczka będzie zgodna z zasadami, będzie mogła uzyskać usługi z sieci. To sprawia, że rozszerzalność jest bardzo łatwa i usuwa lub obniża koszty koordynacji : nie musisz powiadamiać dostawcy energii elektrycznej o tym, jak działa twoje nowe urządzenie, i dojść do osobnej umowy dotyczącej sposobu podłączenia nowego urządzenia do sieci.
Kraje mają standardowe skrajnie szyn. Pozwala to na podział pracy między firmy inżynieryjne, które stawiają szyny, oraz firmy inżynierskie, które budują pociągi, aby jeździć na tych szynach, a także umożliwia przedsiębiorstwom kolejowym wymianę i modernizację pociągów bez ponownej zmiany całego systemu.
Usługę, którą firma przedstawia klientowi, można opisać jako interfejs: dobrze zdefiniowany interfejs podkreśla usługę i ukrywa środki . Po umieszczeniu listu w skrzynce pocztowej oczekujesz, że system pocztowy dostarczy list w określonym czasie, ale nie masz żadnych oczekiwań co do sposobu dostarczenia listu: nie musisz tego wiedzieć , a usługa pocztowa może elastycznie wybierz sposób dostawy, który najlepiej spełnia wymagania i obecne okoliczności. Wyjątkiem jest możliwość wyboru przez klientów poczty lotniczej - nie jest to interfejs, który zaprojektowałby nowoczesny programista, ponieważ ujawnia zbyt wiele implementacji.
Przykłady z natury: Nie przepadam za przykładami eats (), makesSound (), move () itp. Opisują zachowanie, co jest poprawne, ale nie opisują interakcji i sposobu ich włączania . Oczywiste przykłady interfejsów, które umożliwiają interakcje w przyrodzie, dotyczą reprodukcji, na przykład kwiat stanowi pewien interfejs dla pszczoły, dzięki czemu może mieć miejsce zapylenie.
źródło
Jest całkowicie możliwe, aby przejść całe życie jako programista .net i nigdy nie pisać własnych interfejsów. W końcu przetrwaliśmy bez nich dobrze przez dziesięciolecia, a nasze języki wciąż były kompletne w Turingu.
Nie mogę ci powiedzieć, dlaczego potrzebujesz interfejsów, ale mogę dać ci listę miejsc, w których używamy ich w naszym bieżącym projekcie:
W naszym modelu wtyczek ładujemy wtyczki według interfejsu i udostępniamy ten interfejs pisarzom wtyczek, aby były zgodne.
W naszym systemie przesyłania wiadomości między maszynami wszystkie klasy komunikatów implementują określony interfejs i są „rozpakowywane” za pomocą interfejsu.
Nasz system zarządzania konfiguracją definiuje interfejs używany do ustawiania i pobierania ustawień konfiguracji.
Mamy jeden interfejs, którego używamy, aby uniknąć nieprzyjemnego problemu z okrągłym odniesieniem. (Nie rób tego, jeśli nie musisz.)
Sądzę, że jeśli istnieje reguła, należy używać interfejsów, aby zgrupować kilka klas w relacji is-a, ale nie chcesz zapewnić żadnej implementacji w klasie podstawowej.
źródło
Przykład kodu (połączenie Andrzeja z dodatkowymi moimi w interfejsach what-is-the-the-the-of-interfaces ), który również pokazuje, dlaczego interfejs zamiast klasy abstrakcyjnej dla języków bez obsługi wielokrotnego dziedziczenia (c # i Jawa):
Zauważ, że FileLogger i DataBaseLogger nie potrzebują interfejsu (może to być abstrakcyjna klasa bazowa Logger). Uważaj jednak, że musisz użyć zewnętrznego programu rejestrującego, który zmusza Cię do korzystania z klasy bazowej (powiedzmy, że ujawnia chronione metody, których musisz użyć). Ponieważ język nie obsługuje wielokrotnego dziedziczenia, nie będzie można używać abstrakcyjnego podejścia do klasy podstawowej.
Podsumowując: użyj interfejsu, jeśli to możliwe, aby uzyskać dodatkową elastyczność w kodzie. Twoja implementacja jest mniej związana, więc lepiej dostosowuje się do zmian.
źródło
Używałem interfejsów od czasu do czasu i oto moje najnowsze użycie (nazwy zostały uogólnione):
Mam kilka niestandardowych elementów sterujących w WinForm, które muszą zapisywać dane w obiekcie biznesowym. Jednym podejściem jest wywołanie każdej kontroli osobno:
Problem z tą implementacją polega na tym, że za każdym razem, gdy dodam kontrolkę, muszę przejść do mojej metody „Zapisz dane” i dodać nową kontrolkę.
Zmieniłem formanty, aby wdrożyć interfejs ISaveable, który ma metodę SaveToBusinessObject (...), więc teraz moja metoda „Save Data” po prostu iteruje przez formanty, a jeśli znajdzie taką, która jest ISaveable, wywoła SaveToBusinessObject. Teraz, gdy potrzebna jest nowa kontrola, wszystko, co ktoś musi zrobić, to zaimplementować ISaveable w tym obiekcie (i nigdy nie dotykać innej klasy).
Często niezrealizowaną korzyścią dla interfejsów jest lokalizacja modyfikacji. Po zdefiniowaniu rzadko zmieniasz ogólny przepływ aplikacji, ale często wprowadzasz zmiany na poziomie szczegółów. Gdy zachowujesz szczegóły w określonych obiektach, zmiana w ProcessA nie wpłynie na zmianę w ProcessB. (Klasy podstawowe również dają tę korzyść.)
EDYCJA: Kolejną korzyścią jest specyfika działań. Tak jak w moim przykładzie, wszystko, co chcę zrobić, to zapisać dane; Nie dbam o to, jaki to rodzaj kontroli lub czy może zrobić cokolwiek innego - chcę tylko wiedzieć, czy mogę zapisać dane w formancie. Sprawia, że mój kod zapisu jest całkiem jasny - nie ma żadnych sprawdzeń, czy jest to tekst, numer, boolean czy cokolwiek innego, ponieważ formant niestandardowy obsługuje to wszystko.
źródło
Powinieneś zdefiniować interfejs, kiedy będziesz musiał wymusić zachowanie dla swojej klasy.
Zachowanie zwierzęcia może obejmować chodzenie, jedzenie, bieganie itp. Dlatego definiujesz je jako interfejsy.
Innym praktycznym przykładem jest interfejs ActionListener (lub Runnable). Wdrożysz je, gdy chcesz śledzić określone zdarzenie. Dlatego musisz podać implementację
actionPerformed(Event e)
metody w swojej klasie (lub podklasie). Podobnie w przypadku interfejsu Runnable udostępniasz implementacjępublic void run()
metody.Można również zaimplementować te interfejsy dla dowolnej liczby klas.
Innym przykładem użycia interfejsów (w Javie) jest implementacja wielokrotnego dziedziczenia oferowanego w C ++.
źródło
Załóżmy, że chcesz modelować irytacje, które mogą się zdarzyć, gdy próbujesz iść spać.
Model przed interfejsami
Jak wyraźnie widzisz, wiele „rzeczy” może być denerwujących, kiedy próbujesz spać.
Wykorzystanie klas bez interfejsów
Ale jeśli chodzi o korzystanie z tych klas, mamy problem. Nie mają ze sobą nic wspólnego. Każdą metodę musisz wywołać osobno.
Model z interfejsami
Aby rozwiązać ten problem, możemy wprowadzić iterację
I zaimplementuj to w klasach
Użycie z interfejsami
Co znacznie ułatwi korzystanie z tych klas
źródło
Neighbour
iLampJustOutsideYourWindow
też trzeba wdrożyćAnnoying
?Najłatwiejszym przykładem jest coś takiego jak procesory płatności (Paypal, PDS itp.).
Załóżmy, że tworzysz interfejs IPaymentProcessor z metodami ProcessACH i ProcessCreditCard.
Możesz teraz wdrożyć konkretną implementację Paypal. Wywołanie tych metod wywołuje określone funkcje PayPal.
Jeśli później zdecydujesz, że musisz zmienić dostawcę, możesz to zrobić. Po prostu utwórz kolejną konkretną implementację dla nowego dostawcy. Ponieważ wszystko, z czym jesteś związany, to interfejs (umowa), możesz zamienić, którego używa Twoja aplikacja, nie zmieniając kodu, który go zużywa.
źródło
Pozwala także na przeprowadzanie próbnych testów jednostkowych (.Net). Jeśli twoja klasa korzysta z interfejsu, możesz wyśmiewać obiekt w testach jednostkowych i łatwo testować logikę (bez faktycznego odwiedzania bazy danych lub usługi internetowej itp.).
http://www.nmock.org/
źródło
Podczas przeglądania zestawów .NET Framework i drążenia w dół do klas podstawowych dla dowolnego ze standardowych obiektów, zauważysz wiele interfejsów (członków o nazwie ISomeName).
Interfejsy są w zasadzie do implementacji frameworków, dużych lub małych. Tak samo myślałem o interfejsach, dopóki nie chciałem napisać własnego frameworka. Odkryłem również, że zrozumienie interfejsów pomogło mi szybciej nauczyć się ram. W momencie, gdy chcesz napisać bardziej eleganckie rozwiązanie do wszystkiego, przekonasz się, że interfejs ma sens. To jak metoda pozwalająca klasie założyć odpowiednie ubrania do pracy. Co ważniejsze, interfejsy pozwalają systemom na znacznie bardziej samo-dokumentowanie, ponieważ złożone obiekty stają się mniej złożone, gdy klasa implementuje interfejsy, co pomaga kategoryzować jego funkcjonalność.
Klasy implementują interfejsy, gdy chcą mieć możliwość bezpośredniego lub pośredniego uczestnictwa w strukturze. Na przykład, IDisposable to wspólny interfejs, który zapewnia podpis metody dla popularnej i użytecznej metody Dispose (). W środowisku wszystko, co ty lub inny programista powinniście wiedzieć o klasie, to to, że jeśli implementuje ona IDisposable, to wiesz, że ((IDisposable) myObject) .Dispose () można wywołać w celu wyczyszczenia.
PRZYKŁAD KLASYCZNY: bez implementacji interfejsu IDisposable nie można używać konstrukcji słowa kluczowego „using ()” w języku C #, ponieważ wymaga to, aby każdy obiekt określony jako parametr mógł być niejawnie rzutowany na IDisposable.
PRZYKŁAD KOMPLEKSOWY: Bardziej złożonym przykładem byłaby klasa System.ComponentModel.Component. Ta klasa implementuje zarówno IDisposable, jak i IComponent. Większość, jeśli nie wszystkie, obiekty .NET, z którymi jest powiązany projektant wizualny, implementują IComponent, dzięki czemu IDE będzie mogło wchodzić w interakcje z tym komponentem.
WNIOSEK: Gdy zapoznasz się z .NET Framework, pierwszą rzeczą, którą zrobisz, gdy spotkasz nową klasę w Przeglądarce obiektów lub w narzędziu .NET Reflector (darmowym) ( http://www.red-gate.com / products / reflector / ) ma sprawdzić, która klasa dziedziczy, a także interfejsy, które implementuje. .NET Reflector jest jeszcze lepszy niż Przeglądarka obiektów, ponieważ pozwala także zobaczyć klasy pochodne. To pozwala ci dowiedzieć się o wszystkich obiektach, które wywodzą się z konkretnej klasy, a tym samym potencjalnie dowiedzieć się o funkcjonalności frameworku, o której istnieniu nie wiedziałeś. Jest to szczególnie istotne, gdy do .NET Framework zostaną dodane nowe lub nowe przestrzenie nazw.
źródło
Rozważ, że tworzysz strzelankę FPS. Gracz ma do wyboru wiele pistoletów.
Możemy mieć interfejs
Gun
definiujący funkcjęshoot()
.Potrzebujemy różnych podklas
Gun
klasy mianowicieShotGun
Sniper
i tak dalej.Klasa strzelanek
Strzelec ma wszystkie pistolety w swojej zbroi. Stwórzmy to,
List
aby je przedstawić.Strzelec zmienia swoją broń, w razie potrzeby, korzystając z funkcji
switchGun()
Możemy ustawić bieżącą broń, używając powyższej funkcji i po prostu wywołać
shoot()
funkcję, gdyfire()
zostanie wywołana.Zachowanie funkcji fotografowania będzie się różnić w zależności od różnych implementacji
Gun
interfejsu.Wniosek
Utwórz interfejs, gdy funkcja klasy jest zależna od funkcji innej klasy , która podlega zmianie swojego zachowania, w zależności od instancji (obiektu) zaimplementowanej klasy.
na przykład
fire()
funkcja zShooter
klasy oczekuje, że pistolety (Sniper
,ShotGun
) wykonają tęshoot()
funkcję. Więc jeśli zmienimy broń i strzelimy.Zmieniliśmy zachowanie
fire()
funkcji.źródło
Aby rozwinąć to, co powiedział Larsenal. Interfejs to umowa, której muszą przestrzegać wszystkie klasy implementacyjne. Z tego powodu możesz skorzystać z techniki zwanej programowaniem do umowy. Dzięki temu oprogramowanie może stać się niezależne od implementacji.
źródło
Interfejsy są zwykle używane, gdy chcesz zdefiniować zachowanie, które mogą wykazywać obiekty.
Dobrym przykładem tego w świecie .NET jest interfejs IDisposable , który jest używany we wszystkich klasach Microsoft korzystających z zasobów systemowych, które należy ręcznie zwolnić. Wymaga, aby klasa implementująca go miała metodę Dispose ().
(Metoda Dispose () jest także wywoływana przy użyciu konstruktu języka VB.NET i C # , który działa tylko na
IDisposable
s)Należy pamiętać, że można sprawdzić, czy obiekt implementuje określony interfejs, używając konstrukcji takich jak
TypeOf ... Is
(VB.NET),is
(C #),instanceof
(Java) itp.źródło
Ponieważ kilka osób prawdopodobnie już odpowiedziało, interfejsy mogą służyć do wymuszania określonych zachowań między klasami, które nie będą wdrażać tych zachowań w ten sam sposób. Tak więc, implementując interfejs, mówisz, że twoja klasa ma takie zachowanie interfejsu. Interfejs IAnimal nie byłby typowym interfejsem, ponieważ klasy Dog, Cat, Bird itp. Są typami zwierząt i prawdopodobnie powinny go rozszerzać, co jest przypadkiem dziedziczenia. Zamiast tego interfejs byłby bardziej podobny do zachowania zwierząt w tym przypadku, na przykład IRunnable, IFlyable, ITrainable itp.
Interfejsy są dobre dla wielu rzeczy, jedną z kluczowych rzeczy jest podłączalność. Na przykład, zadeklarowanie metody z parametrem List pozwoli na przekazanie wszystkiego, co implementuje interfejs List, umożliwiając programistom usunięcie i podłączenie innej listy w późniejszym czasie bez konieczności przepisywania ton kodu.
Możliwe, że nigdy nie użyjesz interfejsów, ale jeśli projektujesz projekt od zera, zwłaszcza pewnego rodzaju framework, prawdopodobnie będziesz chciał się z nimi zapoznać.
Poleciłbym przeczytać rozdział o interfejsach w Java Design autorstwa Coad, Mayfield i Kern. Wyjaśniają to nieco lepiej niż przeciętny tekst wprowadzający. Jeśli nie używasz Javy, możesz po prostu przeczytać początek rozdziału, który jest po prostu głównie pojęciami.
źródło
Jak każda technika programowania, która zwiększa elastyczność twojego systemu, interfejsy również zwiększają poziom złożoności. Często są świetne i można ich używać wszędzie (możesz stworzyć interfejs dla wszystkich swoich klas) - ale dzięki temu stworzyłbyś bardziej złożony system, który byłby trudniejszy w utrzymaniu.
Jest tutaj jak zwykle kompromis: elastyczność nad łatwością w utrzymaniu. Który jest ważniejszy? Nie ma odpowiedzi - to zależy od projektu. Pamiętaj jednak, że każde oprogramowanie będzie musiało być konserwowane ...
Moja rada: nie używaj interfejsów, dopóki ich naprawdę nie potrzebujesz. (W Visual Studio możesz wyodrębnić interfejs z istniejącej klasy w ciągu 2 sekund - więc nie spiesz się.)
Powiedziawszy to, kiedy trzeba stworzyć interfejs?
Robię to, gdy refaktoryzuję metodę, która nagle musi przetworzyć dwie lub więcej podobnych klas. Następnie tworzę interfejs, przypisuję ten interfejs do dwóch (lub więcej) podobnych klas i zmieniam typ parametru metody (zamieniam typ klasy na typ interfejsu).
I to działa: o)
Jeden wyjątek: kiedy mam wyśmiewać obiekty, interfejs jest znacznie łatwiejszy w użyciu. Dlatego często tworzę interfejs właśnie do tego.
PS: kiedy piszę „interfejs”, mam na myśli: „interfejs dowolnej klasy bazowej”, w tym klasy czystego interfejsu. Zauważ, że klasy abstrakcyjne są często lepszym rozwiązaniem niż czyste interfejsy, ponieważ można do nich dodać logikę.
Pozdrawiam, Sylvain.
źródło
Interfejsy staną się widoczne, gdy zostaniesz programistą biblioteki (kimś, kto koduje inne kodery). Większość z nas zaczyna jako twórcy aplikacji , w których używamy istniejących interfejsów API i bibliotek programistycznych.
W tym samym wierszu, w którym interfejsy są umową , nikt jeszcze nie wspomniał, że interfejsy są doskonałym sposobem na ustabilizowanie niektórych części kodu . Jest to szczególnie przydatne, gdy jest to projekt zespołowy (lub gdy tworzysz kod używany przez innych programistów). Oto konkretny scenariusz:
Zobacz także podobne pytanie dotyczące kodowania interfejsu .
źródło
Interfejs ma tak wiele celów.
Użyj w zachowaniu polimorficznym. Gdzie chcesz wywoływać określone metody klasy podrzędnej z interfejsem mającym odniesienie do klasy podrzędnej.
Zawarcie umowy z klasami na wdrożenie wszystkich metod tam, gdzie jest to konieczne, podobnie jak najczęściej w przypadku obiektów COM, gdzie klasa otoki jest generowana w bibliotece DLL, która dziedziczy interfejs; metody te są wywoływane za kulisami i wystarczy je zaimplementować, ale z taką samą strukturą, jak zdefiniowano w bibliotece DLL COM, którą można poznać tylko poprzez interfejs, który one ujawniają.
Aby zmniejszyć zużycie pamięci, ładując określone metody w klasie. Na przykład, jeśli masz trzy obiekty biznesowe i są one zaimplementowane w jednej klasie, możesz użyć trzech interfejsów.
Np. IUser, IOrder, IOrderItem
Jeśli chcesz tylko dodać użytkownika, wykonaj następujące czynności:
źródło