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

  1. Nazwy interfejsów zaczynaj od I – np. IDrukowalny.
  2. Używaj interfejsów do definiowania kontraktów, aby odseparować implementację od użycia.
  3. Preferuj interfejsy do dziedziczenia wielu funkcjonalności zamiast wielodziedziczenia klas (którego w C# nie ma).
  4. Explicit implementation – stosuj, gdy metoda interfejsu może kolidować z metodami klasy.
  5. Polimorfizm interfejsowy – używaj go do elastycznych i skalowalnych architektur.