interface (C#-verwijzing)
Een interface definieert een contract. Elke class
, of struct
die dat contract implementeert, record
moet een implementatie bieden van de leden die in de interface zijn gedefinieerd. Een interface kan een standaard implementatie definiëren voor leden. Het kan ook leden definiëren static
om één implementatie te bieden voor algemene functionaliteit. Vanaf C# 11 kan een interface definiëren static abstract
of static virtual
leden declareren dat een implementatietype de gedeclareerde leden moet leveren. static virtual
Methoden verklaren doorgaans dat een implementatie een set overbelaste operators moet definiëren.
In het volgende voorbeeld moet de klasse ImplementationClass
een methode implementeren die SampleMethod
geen parameters bevat en retourneert void
.
Zie Interfaces voor meer informatie en voorbeelden.
Een interface op het hoogste niveau, die is gedeclareerd in een naamruimte, maar niet genest binnen een ander type, kan worden gedeclareerd public
of internal
. De standaardwaarde is internal
. Geneste interfacedeclaraties, die binnen een ander type zijn gedeclareerd, kunnen worden gedeclareerd met behulp van elke toegangsaanpassing.
Interfaceleden zonder een implementatie kunnen geen toegangsmodifier bevatten. Leden met een standaard implementatie kunnen alle toegangsaanpassingen bevatten.
Voorbeeldinterface
interface ISampleInterface
{
void SampleMethod();
}
class ImplementationClass : ISampleInterface
{
// Explicit interface member implementation:
void ISampleInterface.SampleMethod()
{
// Method implementation.
}
static void Main()
{
// Declare an interface instance.
ISampleInterface obj = new ImplementationClass();
// Call the member.
obj.SampleMethod();
}
}
Een interface kan lid zijn van een naamruimte of een klasse. Een interfacedeclaratie kan declaraties (handtekeningen zonder enige implementatie) van de volgende leden bevatten:
Standaardinterfaceleden
Deze voorgaande liddeclaraties bevatten doorgaans geen hoofdtekst. Een interfacelid kan een hoofdtekst declareren. Leden in een interface zijn de standaard implementatie. Leden met lichamen stellen de interface in staat om een 'standaard'-implementatie te bieden voor klassen en structs die geen overschrijvende implementatie bieden.
Belangrijk
Het toevoegen van standaardinterfaceleden dwingt alle ref struct
gebruikers die de interface implementeren om een expliciete declaratie van dat lid toe te voegen.
Een interface kan het volgende omvatten:
- Constanten
- Operators
- Statische constructor.
- Geneste typen
- Statische velden, methoden, eigenschappen, indexeerfuncties en gebeurtenissen
- Liddeclaraties met behulp van de expliciete syntaxis van de interface-implementatie.
- Expliciete toegangsaanpassingen (de standaardtoegang is
public
).
Statische abstracte en virtuele leden
Vanaf C# 11 kan een interface declareren en static virtual
leden voor static abstract
alle lidtypen behalve velden. Interfaces kunnen aangeven dat het implementeren van typen operators of andere statische leden moet definiëren. Met deze functie kunnen algemene algoritmen het gedrag van getallen opgeven. U kunt voorbeelden zien in de numerieke typen in de .NET-runtime, zoals System.Numerics.INumber<TSelf>. Deze interfaces definiëren algemene wiskundige operatoren die door veel numerieke typen worden geïmplementeerd. De compiler moet aanroepen en static virtual
static abstract
methoden tijdens het compileren oplossen. De static virtual
methoden die static abstract
in interfaces zijn gedeclareerd, hebben geen runtime-verzendmechanisme dat vergelijkbaar is met virtual
of abstract
methoden die zijn gedeclareerd in klassen. In plaats daarvan gebruikt de compiler typegegevens die beschikbaar zijn tijdens het compileren. static virtual
Daarom worden methoden bijna uitsluitend gedeclareerd in algemene interfaces. Bovendien moeten de meeste interfaces die declareren of methoden declareren static virtual
dat een van de typeparameters de gedeclareerde interface moet implementeren.static abstract
De interface declareert bijvoorbeeld INumber<T>
dat T
moet worden geïmplementeerd INumber<T>
. De compiler gebruikt het typeargument om aanroepen naar de methoden en operators om te voeren die zijn gedeclareerd in de interfacedeclaratie. Het type implementeert INumber<int>
bijvoorbeeld int
. Wanneer de typeparameter het typeargument T
int
aangeeft, worden de static
leden aangeroepen die zijn gedeclareerd int
. double
Als het typeargument is, worden de static
leden die voor het double
type zijn gedeclareerd, ook aangeroepen.
Belangrijk
Methode-verzending voor static abstract
en static virtual
methoden die in interfaces zijn gedeclareerd, wordt opgelost met behulp van het type compileertijd van een expressie. Als het runtimetype van een expressie is afgeleid van een ander type compileertijd, worden de statische methoden op het basistype (compileertijd) aangeroepen.
U kunt deze functie proberen door te werken met de zelfstudie over statische abstracte leden in interfaces.
Overname van interface
Interfaces bevatten mogelijk geen exemplaarstatus. Statische velden zijn nu toegestaan, maar exemplaarvelden zijn niet toegestaan in interfaces. Automatische eigenschappen van exemplaren worden niet ondersteund in interfaces, omdat ze impliciet een verborgen veld declareren. Deze regel heeft een subtiel effect op eigenschapsdeclaraties. In een interfacedeclaratie declareert de volgende code geen automatisch geïmplementeerde eigenschap zoals in een class
of struct
. In plaats daarvan declareert het een eigenschap die geen standaard implementatie heeft, maar moet worden geïmplementeerd in elk type dat de interface implementeert:
public interface INamed
{
public string Name {get; set;}
}
Een interface kan overnemen van een of meer basisinterfaces. Wanneer een interface wordt overgenomen van een andere interface, moet een type dat de afgeleide interface implementeert alle leden in de basisinterfaces implementeren, evenals de leden die zijn gedeclareerd in de afgeleide interface, zoals wordt weergegeven in de volgende code:
public interface I1
{
void M1();
}
public interface I2 : I1
{
void M2();
}
public class C : I2
{
// implements I1.M1
public void M1() { }
// implements I2.M2
public void M2() { }
}
Wanneer een interface een methode overschrijft die is geïmplementeerd in een basisinterface, moet deze de expliciete syntaxis van de interface-implementatie gebruiken.
Wanneer een basistypelijst een basisklasse en interfaces bevat, moet de basisklasse eerst in de lijst komen.
Een klasse die een interface implementeert, kan expliciet leden van die interface implementeren. Een expliciet geïmplementeerd lid kan niet worden geopend via een klasse-exemplaar, maar alleen via een exemplaar van de interface. Daarnaast kunnen standaardinterfaceleden alleen worden geopend via een exemplaar van de interface.
Zie Expliciete interface-implementatie voor meer informatie over expliciete interface-implementatie.
Voorbeeld van interface-implementatie
In het volgende voorbeeld ziet u de interface-implementatie. In dit voorbeeld bevat de interface de eigenschapsdeclaratie en bevat de klasse de implementatie. Elk exemplaar van een klasse die implementeertIPoint
, heeft gehele getallen en y
x
.
interface IPoint
{
// Property signatures:
int X { get; set; }
int Y { get; set; }
double Distance { get; }
}
class Point : IPoint
{
// Constructor:
public Point(int x, int y)
{
X = x;
Y = y;
}
// Property implementation:
public int X { get; set; }
public int Y { get; set; }
// Property implementation
public double Distance =>
Math.Sqrt(X * X + Y * Y);
}
class MainClass
{
static void PrintPoint(IPoint p)
{
Console.WriteLine("x={0}, y={1}", p.X, p.Y);
}
static void Main()
{
IPoint p = new Point(2, 3);
Console.Write("My Point: ");
PrintPoint(p);
}
}
// Output: My Point: x=2, y=3
C#-taalspecificatie
Zie de sectie Interfaces van de C#-taalspecificatie, de functiespecificatie voor C# 8 - Standaardinterfaceleden en de functiespecificatie voor C# 11 - statische abstracte leden in interfaces