Kurs C# cz. 8 – Interfejsy

Ta część nie będzie może za długa, ale poruszę w niej konstrukcję języka, która w dobrych programach jest używana bardzo często. Pomówimy dzisiaj o interfejsach.

Przypomnij sobie tekst gdzie omawiałem budowę klas. Teraz usuń z klas wszystkie zmienne, prywatne metody i ciała metod publicznych – otrzymałeś interfejs ;)

A tak bardziej serio to interfejsy faktycznie mogą delikatnie przypominać klasy, ale na pewno mocno z klasami się łączą. Najłatwiej interfejs w C# będzie chyba wytłumaczyć porównując go do portów w komputerze. Wyobraź sobie, że interfejs jest np. portem USB. Sam port USB określa w jaki sposób są przesyłane dane, jak wygląda gniazdo itd. Ale to jakie konkretnie urządzenie podłączymy już portu USB nie obchodzi, tak samo nie obchodzi go co się stanie dalej z przesłanymi danymi, on tylko mówi jak mają być one przesyłane między komputerem i urządzeniem. Ważne jest tylko, żeby wtyczka pasowała. I właśnie podobnie działają interfejsy – określają sposób komunikowania się między klasami, ale jakie to są konkretnie klasy samego interfejsu już nie obchodzi. Dodatkowo tak samo jak jakieś urządzenie może obsługiwać kilka różnych portów tak samo klasa może implementować kilka interfejsów.

Budowa interfejsu w języku C# jest stosunkowo prosta:

Jak widać słowo class zastąpione zostało słowem interface. Wewnątrz interfejsu mamy deklaracje metod. Same deklaracje bez implementacji ponieważ interfejs służy tylko do zakomunikowania jakiej metody możemy użyć, nie określa jednak co dalej ona będzie robić. Dodatkowo nie użyłem tutaj żadnego słowa kluczowego określającego widoczność dalej metody. Jest tak ponieważ z założenia wszystkie metody w interfejsie będą zaimplementowane jako publiczne, w końcu jaki sens miałaby taka metoda służąca do komunikacji ze światem, która byłaby prywatna i niedostępna poza konkretną klasą?

W nazwie interfejsu przed słowem Usb dodałem literę I. Zrobiłem to nieprzypadkowo. Otóż konwencja nazewnicza języka C# sugeruje żeby nazwy interfejsów właśnie od tej litery się zaczynały i dobrą praktyką jest trzymanie się tego.

Ok, to teraz jak używać tych interfejsów? Jak utworzyć z ich pomocą jakieś obiekty? Interfejsu używamy na dwa sposoby, które są ze sobą ściśle związane.

Po pierwsze interfejs może być implementowany przez klasę. Korzystając z pokazanego przed chwilą interfejsu wygląda to w ten sposób:

Jak widać aby klasa implementowała dany interfejs podajemy jego nazwę za nazwą klasy, po dwukropku. Następnie już wewnątrz samej klasy musimy zdefiniować wszystkie metody, które dostarcza interfejs. Dodatkowo muszą one być publiczne.

Jeśli chcielibyśmy aby klasa implementowała kilka interfejsów podajemy kolejne nazwy po przecinku. Tutaj przykład klasy implementującej 3 interfejsy:

Oczywiście wewnątrz klasy powinny się znaleźć wszystkie metody dostarczane przez te interfejsy.

Teraz pora na drugi sposób użycia interfejsu – użycie go jako typu zmiennej. W tym momencie cały sens użycia interfejsów stanie się bardziej przejrzysty.

Tak jak w poprzednich częściach kursu mogłeś utworzyć zmienne, których typem była konkretna klasa, którą utworzyłeś tak samo możesz utworzyć zmienne, których typem będzie interfejs. Pozostając przy pokazanych wcześniej przykładach:

Tutaj magii nie ma. Dodaliśmy zmienną typu IUsb. Ale co teraz? Nie możemy utworzyć obiektu IUsb poprzez  new IUsb();  ponieważ nie da się utworzyć obiektu interfejsu. I teraz właśnie zaczyna się magia związana z interfejsami. Do tak przygotowanej zmiennej możemy przypisać obiekt klasy implementującej dany interfejs:

Korzystając teraz z tej zmiennej będziemy mieli dostęp tylko do metod, które w danym interfejsie zadeklarowaliśmy nawet jeśli ta konkretna klasa posiadała by ich więcej.

Gdyby w naszym programie było kilka klas, które implementują ten interfejs możliwe by było przypisanie obiektów z nich utworzonych do podanej powyżej zmiennej i używanie implementacji metod z każdej z nich.

Dobrym przykładem tutaj są kolekcje czy tablice w języku C#. Większość z nich implementuje interfejs IEnumerable, który określa m.in. że dostępne są metody pozwalające przechodzić po kolejnych elementach kolekcji jednak w żaden sposób nie narzuca tego jak dana klasa będzie to obsługiwała pod spodem. Dzięki temu niezależnie od tego której kolekcji użyjemy możemy mieć pewność, że każda z nich będzie zawierała pewien zestaw metod, które możemy wykorzystać. Z tego faktu korzystają chociażby biblioteki dostarczone wraz z frameworkiem .NET, które pozwalają np. sortować kolekcje. Nie obchodzi ich jaka kolekcja jest użyta i w jaki sposób przechowuje dane. Im wystarczy, że mogą np. wywołać metodę Next() itp.

Tak jak możemy tworzyć zmienne, których typem jest interfejs tak samo możemy dodawać metody, które przyjmują bądź zwracają interfejs i jest to najczęściej używana cecha tych konstrukcji. Przykładowa metoda może wyglądać w ten sposób (zakładamy, że IUsb i ICom to interfejsy dodane w naszym programie):

Powyższa metoda przyjmuje jako parametr obiekt klasy implementującej interfejs IUsb i zwraca obiekt klasy implementującej interfejs ICom.

 

I to na tyle jeśli chodzi o tą część kursu dotyczącą interfejsów. Przekazałem Wam tutaj większość niezbędnych informacji dotyczących tej konstrukcji językowej. Być może na początku nie za bardzo będziecie czuli sens stosowania interfejsów jednak polecam próbować dodawać je czasami nawet na siłę tam gdzie następuje komunikacja pomiędzy różnymi klasami. Metoda jakiejś klasy przyjmuje w parametrze obiekt innej klasy? Dodaj interfejs z metodami z drugiej klasy, które są używane przez pierwszą, spraw żeby druga klasa go implementowała, a w metodach pierwszej klasy zamień typ parametru z drugiej klasy na interfejs, który ona implementuje.

10 przemyśleń nt. „Kurs C# cz. 8 – Interfejsy

  1. Ciekawy wpis, też mam własnego bloga o języku C#(i nie tylko) mógłby Pan go ocenić, przydałaby mi się porada eksperta.

    1. Aktualnie nie mam zaplanowanej kolejnej części, ale jeśli wpadnie mi temat, który uznam za warty opisania lub ktoś z czytelników zasugeruje co mogłoby być dalej to nie wykluczam kolejnych części.

    1. Znajomość programowania to nie tylko znajomość języka ale też dodatkowych bibliotek, frameworków i różnych dobrych praktyk. Ten kurs jest tylko podstawą do nauki C# ale po jego skończeniu będziesz rozumiał kod w tutorialach np. do ASP.NET, WPF czy innych frameworków lub bibliotek.
      To co tutaj pokazuję pozwala co najwyżej pisać proste aplikacje konsolowe.

  2. Witam Panie Marku !

    Mam pytanie a mianowicie, czy po ukończeniu Pańskiego kursu będę w stanie zacząć programować proste gry na konsoli bądź w Unity3d ?

    1. Witam :)
      Ukończenie tego kursu jak najbardziej daje podstawy żeby zacząć się bawić takimi rzeczami. Zwłaszcza jeśli chodzi o Unity gdzie z C# ważne jest poznanie podstaw, a potem całość opiera się w dużej mierze na kilku mechanizmach i masie klas i metod od Unity.

  3. Witam, swietny blog nakreslajacy jezyk, tylko gdzie szukac dokumentacji jak z api javy gdzie wszystkie klasy itd sa omowine i wyjaśnione. Chcac napisac jakis program musze wiedziec gdzie szukać. Z podstaw jak Pan wspomnial oblicze co najwyzej rownanie kwadratwe. Prosze o rozwiniecie jak i skad dalej sie uczyc.

Dodaj komentarz

Twój adres email nie zostanie opublikowany. Pola, których wypełnienie jest wymagane, są oznaczone symbolem *