Interfejs klasy — w obiektowych językach programowania interfejs jest abstrakcyjną reprezentacją klasy pozwalającą na korzystanie z niej niezależnie od faktycznej implementacji. Interfejs pozwala na enkapsulację wielu różnych obiektów utworzonych w oparciu o odmienne klasy, które zawierają implementację wspólnego interfejsu. [wikipedia]
Interfejs dostarcza nam pewną funkcjonalność którą realizują klasy implementujące go, dzięki czemu możemy posługiwać się wyłącznie interfejsem aby zrealizować konkretne zadania bez konieczności zagłębiania się w kod znajdujący się za nimi.
Interfejsy w C#
W języku C# definiując interfejs posługujemy się słowem kluczowym interface, trzeba pamiętać że przy tworzeniu interfejsu nie używamy modyfikatorów dostępu, gdyż wszystkie elementy zawarte w interfejsie są publiczne. W interfejsach tworzymy jedynie definicje wybranych elementów które muszą zaimplementować klasy/struktury je implementujące.
Interfejsy mogą zawierać deklarację:
- metod
- właściwości
- zdarzeń
- indekserów
Interfejsy nie mogą zawierać stałych, pól, operatorów, konstruktorów, destruktorów i zagnieżdżonych typów. Nie mogą zawierać również statycznych elementów.
Interfejsy mogą dziedziczyć po jednym lub kilku interfejsach. Elementami implementującymi interfejsy są klasy lub struktury (mogą on implementować wiele interfejsów). W języku C# mamy również możliwość tworzenia generycznych interfejsów.
Niejawna implementacja interfejsu
Niejawna implementacja interfejsu jest najbardziej znaną formą implementacji. Polega ona na zaimplementowaniu publicznych elementów których definicje zawiera interfejs:
[csharp]
interface ISampleInterface1
{
void Print();
string Message { get; }
}
interface ISampleInterface2
{
void Print();
}
class SampleClass : ISampleInterface1, ISampleInterface2
{
// Zarówno ISampleInterface1.Print i ISampleInterface2.Print
// wywołają tą metodę
public void Print()
{
Console.WriteLine("Metoda Print");
}
private string _message = "";
public string Message
{
get { return _message; }
set { _message = value; }
}
}
[/csharp]
Jak widzimy nie ma tu żadnej magi implementujemy w klasie SampleClass metodę Print i właściwość Message z interfejsu ISampleInterface1 do której dopisujemy setter.
Jawna implementacja interfejsu
Aby jawnie zaimplementować interfejs musimy nazwę implementowanego elementu poprzedzić nazwą interfejsu:
[csharp]
class SampleClass : ISampleInterface1, ISampleInterface2
{
void ISampleInterface1.Print()
{
Console.WriteLine("ISampleInterface1.Print");
}
void ISampleInterface2.Print()
{
Console.WriteLine("ISampleInterface2.Print");
}
private string _message = "";
string ISampleInterface1.Message
{
get { return _message; }
}
}
[/csharp]
Dzięki jawnej implementacji mamy możliwość zaimplementowani dwóch metod o tej samej nazwie co czasami może być niezmiernie przydatne. Przy jawnej implementacji trzeba pamiętać, że nie możemy używać modyfikatorów dostępu. Z jawną implementacją wiąże się też kilka niedogodności: implementacje elementów interfejsu nie są widoczne w klasie implementujące, aby uzyskać do nich dostęp musimy posługiwać się konkretny interfejsem. W przypadku właściwości Message nie możemy dopisać settera gdyż dostaniemy błąd kompilacji.
Więcej informacji na temat interfejsów można uzyskać w:
Interfaces (C# Programming Guide), Explicit Interface Implementation, Explicit Interface Implementation Tutorial, Implicit and Explicit Interface Implementations, Design Guideline Update: Explicit Member Implementation, Interface layout, Interface (C# Reference),