Mehrfache Interfaces
Teil des Abschnitts Objektorientierte Programmierung der C#-Journey von Coddy — Lektion 27 von 70.
Während eine Klasse nur von einer Basisklasse erben kann, kann sie so viele Interfaces wie nötig implementieren. Dies ist einer der Hauptvorteile, die Interfaces gegenüber abstrakten Klassen haben – sie ermöglichen es einer Klasse, mehrere Verhaltensweisen anzunehmen.
Um mehrere Schnittstellen zu implementieren, listen Sie diese einfach nach dem Doppelpunkt auf, getrennt durch Kommas:
public interface IFlyable
{
void Fly();
}
public interface ISwimmable
{
void Swim();
}
public class Duck : IFlyable, ISwimmable
{
public void Fly()
{
Console.WriteLine("Flying through the air");
}
public void Swim()
{
Console.WriteLine("Swimming in the pond");
}
}Die Klasse Duck muss alle Member beider Interfaces implementieren. Dies bildet Szenarien aus der realen Welt auf natürliche Weise ab – eine Ente kann tatsächlich sowohl fliegen als auch schwimmen, daher ist es sinnvoll, dass sie beide Verträge erfüllt.
Bei der Kombination von Vererbung mit mehreren Schnittstellen muss die Basisklasse zuerst kommen:
public class Duck : Bird, IFlyable, ISwimmable
{
// Erbt von Bird, implementiert beide Schnittstellen
}Diese Flexibilität ermöglicht es Ihnen, Verhaltensweisen aus mehreren Quellen zusammenzustellen. Ein Robot könnte IMovable, IChargeable und ISpeakable implementieren. Jedes Interface repräsentiert eine einzelne Fähigkeit, und Ihre Klasse kann genau das kombinieren, was sie benötigt.
Aufgabe
EinfachLassen Sie uns ein Smart-Home-Gerätesystem bauen, das demonstriert, wie eine einzelne Klasse mehrere Schnittstellen implementieren kann, um verschiedene Fähigkeiten zu erlangen. Sie werden Geräte erstellen, die sowohl steuerbar sind als auch über Funktionen zur Energieverwaltung verfügen.
Sie werden Ihren Code über vier Dateien organisieren:
IControllable.cs: Definieren Sie ein Interface namensIControllableim NamespaceSmartHome. Dieses Interface repräsentiert Geräte, die ein- und ausgeschaltet werden können. Es sollte zwei Methoden deklarieren:TurnOn()undTurnOff(), die beide einen String zurückgeben.INetworkConnected.cs: Definieren Sie ein Interface namensINetworkConnectedim NamespaceSmartHome. Dieses Interface repräsentiert Geräte, die sich mit einem Netzwerk verbinden können. Es sollte eine MethodeConnect(string network)deklarieren, die einen String zurückgibt.SmartTV.cs: Definieren Sie eine KlasseSmartTVim NamespaceSmartHome, die sowohlIControllableals auchINetworkConnectedimplementiert. Der Fernseher sollte eine EigenschaftBrand(String) und eine EigenschaftScreenSize(int, repräsentiert Zoll) haben. Erstellen Sie einen Konstruktor, der beide Werte akzeptiert. Implementieren Sie alle Interface-Methoden:TurnOn()gibt"{Brand} {ScreenSize}-inch TV is now ON"zurückTurnOff()gibt"{Brand} {ScreenSize}-inch TV is now OFF"zurückConnect(string network)gibt"{Brand} TV connected to {network}"zurück
Program.cs: Erstellen Sie in Ihrer Hauptdatei einenSmartTVunter Verwendung von Eingabewerten. Demonstrieren Sie die Flexibilität mehrerer Schnittstellen, indem Sie dasselbe TV-Objekt in drei verschiedenen Variablentypen speichern: dem konkreten TypSmartTV, einerIControllable-Variable und einerINetworkConnected-Variable. Rufen Sie die entsprechenden Methoden über jede Referenz auf, um zu zeigen, wie dasselbe Objekt unterschiedlich behandelt werden kann, je nachdem, mit welchem Interface Sie arbeiten.
Sie erhalten drei Eingaben:
- TV-Markenname
- Bildschirmgröße in Zoll
- Netzwerkname, mit dem verbunden werden soll
Geben Sie die Ausgabe in diesem Format aus:
Via SmartTV:
{TurnOn() result}
{Connect(network) result}
Via IControllable:
{TurnOff() result}
Via INetworkConnected:
{Connect(network) result}Wenn die Eingaben beispielsweise Samsung, 55 und HomeWiFi sind, sollte die Ausgabe wie folgt aussehen:
Via SmartTV:
Samsung 55-inch TV is now ON
Samsung TV connected to HomeWiFi
Via IControllable:
Samsung 55-inch TV is now OFF
Via INetworkConnected:
Samsung TV connected to HomeWiFiBeachten Sie, wie auf dasselbe SmartTV-Objekt über verschiedene Interface-Referenzen zugegriffen werden kann. Wenn es als IControllable gespeichert ist, können Sie nur Steuerungsmethoden aufrufen. Wenn es als INetworkConnected gespeichert ist, können Sie nur Netzwerk-Methoden aufrufen. Dies ist die Stärke der Implementierung mehrerer Schnittstellen - eine Klasse erhält mehrere Fähigkeiten und bleibt gleichzeitig flexibel in ihrer Verwendung!
Spickzettel
Eine Klasse kann mehrere Schnittstellen implementieren, indem sie nach dem Doppelpunkt, durch Kommas getrennt, aufgelistet werden:
public interface IFlyable
{
void Fly();
}
public interface ISwimmable
{
void Swim();
}
public class Duck : IFlyable, ISwimmable
{
public void Fly()
{
Console.WriteLine("Flying through the air");
}
public void Swim()
{
Console.WriteLine("Swimming in the pond");
}
}Die Klasse muss alle Member aller Schnittstellen implementieren.
Wenn Vererbung mit mehreren Schnittstellen kombiniert wird, muss die Basisklasse zuerst stehen:
public class Duck : Bird, IFlyable, ISwimmable
{
// Erbt von Bird, implementiert beide Schnittstellen
}Dies ermöglicht das Zusammensetzen von Verhaltensweisen aus mehreren Quellen, wobei jede Schnittstelle eine einzelne Fähigkeit repräsentiert.
Probier es selbst
using System;
using SmartHome;
class Program
{
public static void Main(string[] args)
{
// Eingaben lesen
string brand = Console.ReadLine();
int screenSize = Convert.ToInt32(Console.ReadLine());
string network = Console.ReadLine();
// TODO: Erstellen Sie ein SmartTV-Objekt mit den Eingabewerten
// TODO: Speichern Sie dasselbe TV-Objekt in drei verschiedenen Variablentypen:
// 1. SmartTV-Typ (konkrete Klasse)
// 2. IControllable-Typ (Interface-Referenz)
// 3. INetworkConnected-Typ (Interface-Referenz)
// TODO: Ausgabe im erforderlichen Format drucken:
// Via SmartTV:
// - TurnOn() und Connect(network) aufrufen
// Via IControllable:
// - TurnOff() aufrufen
// Via INetworkConnected:
// - Connect(network) aufrufen
}
}
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.
Alle Lektionen in Objektorientierte Programmierung
1Grundlagen der OOP
Externe DateienNamespaces & DirektivenEinführung in Klassen & ObjekteDas 'this'-SchlüsselwortMethoden und ParameterFelder vs. EigenschaftenKonstruktorenObjekt-InitialisiererZusammenfassung - Einfacher Taschenrechner4Vererbung
Grundlagen der Vererbung (:) SyntaxDas 'base'-SchlüsselwortVirtual & Override SchlüsselwörterVersiegelte KlassenDie 'object'-BasisklasseZusammenfassung – Mitarbeiter-Hierarchie7Fortgeschrittene Funktionen
OperatorüberladungIndexer (this[])ToString() überschreibenErweiterungsmethodenZusammenfassung - Benutzerdefinierte Liste2Eigenschaften & Statische Member
Automatisch implementierte EigenschaftenRead-Only- & Write-Only-EigenschaftenStatische Felder & MethodenStatische KlassenExpression-Bodied Member5Polymorphismus & Interfaces
Compile- vs. Runtime-PolymorphismusInterface vs. abstrakte KlasseMehrfache InterfacesExplizite InterfacesUpcasting & DowncastingRecap – Shape Calculator3Klassenarchitektur
Instanz- vs. statische Daten'readonly' & 'const' SchlüsselwörterBacking FieldsZusammenfassung - Bankkonto-Manager6Kapselung
ZugriffsmodifikatorenProperties zur KapselungImplementierung von Data HidingImmutability-MusterRückblick – Studierendendaten