Interfejsy w C#
1. Wprowadzenie
Interfejs w C# to typ referencyjny, który definiuje kontrakt – zestaw metod, właściwości, zdarzeń lub indeksatorów, które muszą zostać zaimplementowane w klasach lub strukturach, które go implementują.
- Interfejs nie zawiera implementacji metod (chyba że używamy domyślnych implementacji w C# 8.0+).
- Interfejsy umożliwiają polimorfizm i odseparowanie kontraktu od implementacji.
2. Definicja interfejsu
Składnia:
Uwagi:
- Nazwy interfejsów w C# zazwyczaj zaczynają się od
I. - Wszystkie członki interfejsu są domyślnie publiczne i abstrakcyjne – nie używamy modyfikatorów dostępu.
3. Implementacja interfejsu
Klasa lub struktura, która implementuje interfejs, musi zaimplementować wszystkie jego członki:
Użycie:
Zmienna typu interfejsu może przechowywać obiekt dowolnej klasy, która go implementuje – polimorfizm interfejsowy.
4. Interfejsy a wielodziedziczenie
C# nie pozwala klasom dziedziczyć po wielu klasach, ale umożliwia implementację wielu interfejsów:
Dzięki temu można łączyć różne funkcjonalności w jednej klasie bez konfliktu z zasadą pojedynczego dziedziczenia klas.
5. Właściwości interfejsów
-
Interfejs może zawierać:
-
Metody
- Właściwości
- Zdarzenia
- Indeksatory
6. Interfejsy z domyślną implementacją (C# 8.0+)
Od C# 8.0 można w interfejsach definiować domyślną implementację metody, co ułatwia rozwijanie interfejsów bez łamania istniejącego kodu:
7. Różnica między klasą abstrakcyjną a interfejsem
| Cecha | Interfejs | Klasa abstrakcyjna |
|---|---|---|
| Dziedziczenie | Klasa może implementować wiele | Klasa może dziedziczyć tylko jedną |
| Implementacja | Brak implementacji (chyba że domyślna) | Może mieć implementację |
| Pola | Nie można (od C# 8.0 – statyczne lub const) | Tak, dowolne |
| Konstruktory | Brak | Tak |
| Modyfikatory dostępu | Wszystko publiczne | private, protected, public |
8. Polimorfizm interfejsowy
Dzięki interfejsom możemy traktować różne obiekty w ten sam sposób:
Polimorfizm interfejsowy pozwala pisać kod niezależny od konkretnej klasy, tylko od kontraktu, który implementuje.
9. Explicit vs Implicit Implementation
9.1 Implementacja jawna (Explicit)
- Ukrywa metodę interfejsu przed bezpośrednim wywołaniem przez klasę.
- Można wywołać metodę tylko przez zmienną typu interfejsu.
9.2 Implementacja niejawna (Implicit)
- Metoda klasy jest od razu publiczna i może być wywołana przez klasę i interfejs.
10. Dobre praktyki
- Nazwy interfejsów zaczynaj od
I– np.IDrukowalny. - Używaj interfejsów do definiowania kontraktów, aby odseparować implementację od użycia.
- Preferuj interfejsy do dziedziczenia wielu funkcjonalności zamiast wielodziedziczenia klas (którego w C# nie ma).
- Explicit implementation – stosuj, gdy metoda interfejsu może kolidować z metodami klasy.
- Polimorfizm interfejsowy – używaj go do elastycznych i skalowalnych architektur.