2012-02-26 21 views
6

Powiel możliwe:
Interfaces: Why can't I seem to grasp them?
Why would I want to use Interfaces?Dlaczego potrzebuję interfejsu?

Myślę, że to pytanie jest powtarzane 1000 razy i przepraszam za pytanie ponownie. Naprawdę szukam prostej, prostej odpowiedzi, dlaczego wyraźnie potrzebuję interfejsu, lub jeśli wytłumaczysz coś, czego nie mogę osiągnąć bez interfejsu.

Jeśli jest to dziedziczenie wielokrotne, prosiłbym o podanie jednego prostego przykładu, dzięki któremu rozumiem, dlaczego potrzebuję interfejsu.

- Z góry.

Uwaga: Pytam to pytanie w kontekście .NET (C#) język

Edit1: Teraz gdy próbuję nauczyć Interfejs moich myślach mówi mi -> „kolego masz zamiar zarysuj czyjeś ciało w białym prześcieradle "Ale potrzebujesz kolejnego białego prześcieradła, w którym musisz ponownie narysować kontur, narysować wszystkie części ciała, wypełnić je kolorami, aby uzyskać prawdziwy obraz." Więc dlaczego marnuję pierwszy biały arkusz tylko po to, aby uzyskać konspekt: ​​

+0

Może to pomóc: interfejsy opisują * atrybuty * peryferyjne *, klasy abstrakcyjne definiują * funkcje * core. – Jason

+0

jeśli chcesz, aby twój projekt obsługiwał różne bazy danych. tak, że klient może zmienić swoją bazę danych w przyszłości używamy interfejsów zawierających procedury właściwości w pliku klasy bez zmian obiektów ........ –

+0

Istnieją dziesiątki potencjalnych duplikatów tego pytania ... Oto kilka: [1 ] (http://stackoverflow.com/questions/240152/why-would-i-want-to-use-interfaces), [2] (http://stackoverflow.com/questions/3355408/explaining-interfaces-to -students), [3] (http://stackoverflow.com/questions/122883/interfaces-why-cant-i-seem-to-grasp-them) –

Odpowiedz

12

Najłatwiejszym sposobem zrozumienia interfejsów jest umożliwienie różnym obiektom eksponowanie funkcji WSPÓLNEJ. Dzięki temu programiści mogą napisać znacznie prostszy, krótszy kod, który programuje do interfejsu, pod warunkiem, że obiekty będą implementować ten interfejs.

Providers

Database:

Istnieje wiele różnych dostawców baz danych, MySQL, MSSQL, Oracle, itd. Jednak wszystkie obiekty bazy danych może robić te same rzeczy, więc można znaleźć wiele interfejsów dla obiektów bazy danych. Jeśli obiekt implementuje IDBConnection, wówczas ujawnia metody Open() i Close(). Jeśli więc chcę, aby mój program był agnostykiem bazy danych, programuję interfejs, a nie konkretnych dostawców.

IDbConnection connection = GetDatabaseConnectionFromConfig() 
connection.Open() 
// do stuff 
connection.Close() 

Patrz przez programowania do interfejsu (IDbconnection) mogę teraz SWAP z dowolnego dostawcy danych w moim config ale mój kod pozostaje dokładnie taki sam. Ta elastyczność może być niezwykle przydatna i łatwa w utrzymaniu. Wadą tego jest to, że mogę wykonywać tylko "ogólne" operacje na bazach danych i może nie w pełni wykorzystywać siłę, jaką oferuje każdy poszczególny dostawca, tak jak przy wszystkim programowaniu, z którym masz kompromis i musisz ustalić, który scenariusz przyniesie ci najwięcej korzyści.

Kolekcje:

Jeśli zauważysz niemal wszystkie kolekcje wdrożyć ten interfejs o nazwie IEnumerable. IEnumerable zwraca IEnumerator, który ma MoveNext(), Current i Reset(). Pozwala to C# łatwo przejść przez swoją kolekcję. Dzieje się tak dlatego, że eksponuje interfejs IEnumerable, który WIEM, że obiekt udostępnia metody, które musi przejść. To robi dwie rzeczy. 1) pętle foreach będą teraz wiedzieć, jak wyliczyć kolekcję i 2) możesz teraz zastosować potężne expresje LINQ do swojej kolekcji. Znowu powodem, dla którego interfejsy są tutaj tak przydatne, jest to, że wszystkie kolekcje mają coś wspólnego, dlatego można je przenosić. Każda kolekcja może być przenoszona w inny sposób (połączona lista względem tablicy), ale to jest piękno interfejsów, że implementacja jest ukryta i nie ma znaczenia dla konsumenta interfejsu. MoveNext() daje następny element w kolekcji, nie ma znaczenia JAK to robi. Całkiem miło, co?

Polimorfizm

Kiedy projektujesz własne interfejsy po prostu trzeba zadać sobie jedno pytanie. Co te rzeczy mają ze sobą wspólnego? Po znalezieniu wszystkich obiektów, które udostępniają obiekty, można je przekształcić w interfejs, aby każdy obiekt mógł z niego dziedziczyć. Następnie możesz programować przeciwko kilku obiektom używając jednego interfejsu.

I oczywiście muszę podać mój ulubiony polimorficzny przykład C++, przykład zwierząt. Wszystkie zwierzęta mają pewne cechy. Powiedzmy, że mogą się ruszać, mówić, a wszystkie mają imię. Ponieważ właśnie zidentyfikowałem to, co mają wszystkie moje zwierzęta, i mogę je opisać w interfejsie IAnimal. Następnie tworzę obiekt Bear, obiekt Owl i obiekt Snake, wszystkie implementujące ten interfejs.Powodem, dla którego można przechowywać różne obiekty razem, które implementują ten sam interfejs, jest fakt, że interfejsy reprezentują replikację IS-A. Niedźwiedź IS-A, zwierzę Sowa-I-A, dzięki czemu mogę zebrać je wszystkie jako Zwierzęta.

var animals = new IAnimal[] = {new Bear(), new Owl(), new Snake()} // here I can collect different objects in a single collection because they inherit from the same interface 

foreach (IAnimal animal in animals) 
{ 
    Console.WriteLine(animal.Name) 
    animal.Speak() // a bear growls, a owl hoots, and a snake hisses 
    animal.Move() // bear runs, owl flys, snake slithers 
} 

Widać, że chociaż zwierzęta te wykonać każde działanie w inny sposób, mogę zaprogramować przed nimi wszystkimi w jednym zunifikowanego modelu i jest to tylko jedna z wielu korzyści płynących z interfejsami.

Tak więc najważniejszą rzeczą związaną z interfejsami jest to, co mają wspólne obiekty, dzięki czemu można programować przeciwko RÓŻNYM obiektom w sposób SAMOWY. Oszczędza czas, tworzy bardziej elastyczne aplikacje, ukrywa złożoność/implementację, modeluje rzeczywiste obiekty/sytuacje i wiele innych korzyści.

Mam nadzieję, że to pomoże.

+2

Doskonała odpowiedź. –

+0

Jedno z najlepszych wyjaśnień racjonalności używania interfejsu. – rajibdotnet

+0

Dodawanie tej odpowiedzi do zakładek. +1. – Jogi

6

Interfejs to Kontrakt za to, co klasa może zrobić, oznacza to, że jedna klasa może spełniać wiele umów s.

Klasa abstrakcyjna jest szablonem zachowania klasy, można wypełnić tylko jeden szablon na klasę.

Rozszerzona klasa pobiera istniejący obiekt i dodaje/zmienia funkcjonalność, można rozszerzyć tylko jedną klasę nadrzędną dla każdej klasy.

Możesz użyć umowy (interfejsu), jeśli chcesz opisać, jak coś powinno działać, bez definiowania konkretnej implementacji. Kontrakt ten może być spełniony przez dowolną inną klasę, która implementuje zdefiniowane metody/właściwości.

Można użyć klasy abstrakcyjnej, jeśli chcesz określić część funkcji z góry, a następnie dodać do niej.

EDIT: Rozważ to:

Masz aplikację, która potrzebuje do przechowywania niektóre dane Say EntityA ale może masz wiele sposobów, w którym można przechowywać dane (np XML, bazy danych SQL, CSV ect). Można utworzyć klasę dla każdej z tych różnych metod do przechowywania EntityA. ale gdy chciałeś zmienić metodę, musisz dokładnie określić, który typ chcesz tam.

tj

public class DoStuffWithEntityA{ 
    public void DoStuffAndStoreAsXml(EntityA entity){ /*Logic*/} 
    public void DoStuffAndStoreAsCsv(EntityA entity){ /*Logic*/} 
    public void DoStuffAndStoreInDatabase(EntityA entity){ /*Logic*/} 
} 

prehaps lepszym sposobem jest użycie tutaj interfejs, który opisuje, co w ogóle coś, co przechowuje EntityA będzie wyglądać.

np

public interface IStoreEntityA{ 
    void Store(EnitityA entity); 
} 

następnie można po prostu powiedzieć, że chcesz coś, co przechowuje EntityA w kodzie

public class DoStuffWithEntityA{ 
    private IStoreEntityA _entityAStorer; 
    public DoStuffWithEntityA(IStoreEntityA howIStoreEntityA){ _entityAStorer = howIStoreEntityA;} 
    public void DoStuff(EntityA entity) 
    { 
     //Do Stuff 
     _entityAStorer.Store(entity); 
    } 
} 

Oznacza to logika existing ściśle sprzężona do sposobu przechowywania EntityA

+0

Dzięki za odpowiedź. Ale jeśli przeczytasz moją nową edycję, zrozumiesz, co dzieje się w moim umyśle. Będzie pomocne, jeśli dasz mi przykład. Thx –

+0

Zobacz moją edycję scenariusza tutaj, w zasadzie czasami możesz nie chcieć/musisz wiedzieć, jak coś jest zaimplementowane, więc po prostu poprosisz o wszystko, co spełnia konkretną umowę. –

Powiązane problemy