Einführung in Schnittstellen
Teil des Abschnitts Objektorientierte Programmierung der GO-Journey von Coddy. Lektion 25 von 107.
Ein Interface in Go definiert eine Reihe von Methodensignaturen, ohne sie zu implementieren. Es beschreibt, was ein Typ tun kann, nicht, wie er es tut. Jeder Typ, der alle Methoden eines Interfaces implementiert, erfüllt dieses Interface automatisch.
So definierst du ein Interface:
type Speaker interface {
Speak() string
}Dieses Speaker-Interface verlangt, dass jeder implementierende Typ über eine Speak()-Methode verfügt, die einen String zurückgibt. Nun kann jede Struktur mit dieser Methode überall dort verwendet werden, wo ein Speaker erwartet wird.
type Dog struct {
Name string
}
func (d Dog) Speak() string {
return d.Name + " says woof!"
}
type Cat struct {
Name string
}
func (c Cat) Speak() string {
return c.Name + " says meow!"
}Sowohl Dog als auch Cat erfüllen das Speaker-Interface, da sie jeweils über eine Speak()-Methode mit der korrekten Signatur verfügen. Du kannst nun Funktionen schreiben, die jeden beliebigen Speaker akzeptieren:
func MakeSound(s Speaker) {
fmt.Println(s.Speak())
}
func main() {
dog := Dog{Name: "Buddy"}
cat := Cat{Name: "Whiskers"}
MakeSound(dog) // Buddy sagt Wuff!
MakeSound(cat) // Whiskers sagt Miau!
}Schnittstellen ermöglichen es dir, flexiblen, wiederverwendbaren Code zu schreiben, der mit jedem Typ funktioniert, der die Anforderungen der Schnittstelle erfüllt, unabhängig von der zugrunde liegenden Implementierung.
Aufgabe
EinfachErstellen wir ein Fahrzeugbeschreibungssystem, das zeigt, wie Schnittstellen es verschiedenen Typen ermöglichen, ein gemeinsames Verhalten zu teilen. Du erstellst eine Schnittstelle, die mehrere Fahrzeugtypen erfüllen können, und verwendest sie anschließend, um jedes Fahrzeug einheitlich zu beschreiben.
Du organisierst deinen Code über zwei Dateien:
vehicles.go: Definiere eineDescriber-Schnittstelle mit einer einzigen MethodeDescribe() string. Erstelle anschließend zwei Strukturen, die diese Schnittstelle erfüllen:Carmit den FeldernBrandundModel(beide vom Typ String)Bicyclemit den FeldernType(String) undGears(Int)
Describe()-Methode besitzen, die eine beschreibende Zeichenkette über das Fahrzeug zurückgibt.main.go: Erstelle eine Funktion namensPrintDescription, die jedesDescriber-Objekt akzeptiert und das Ergebnis des Aufrufs seinerDescribe()-Methode ausgibt. Lies die Fahrzeuginformationen aus der Eingabe ein, erstelle sowohl ein Car als auch ein Bicycle und verwende deine Funktion, um die Beschreibungen für beide auszugeben.
Die folgenden Eingaben werden bereitgestellt:
- Zeile 1: Marke des Car
- Zeile 2: Modell des Car
- Zeile 3: Typ des Bicycle
- Zeile 4: Anzahl der Gänge (Ganzzahl)
Deine Describe()-Methoden sollten Zeichenketten in diesen Formaten zurückgeben:
- Car:
[Brand] [Model] - Bicycle:
[Type] bike with [Gears] gears
Wenn beispielsweise Toyota, Camry, Mountain und 21 angegeben werden, sollte deine Ausgabe folgendermaßen aussehen:
Toyota Camry
Mountain bike with 21 gearsDie zentrale Erkenntnis ist, dass deine Funktion PrintDescription mit jedem Typ funktioniert, der über eine Describe()-Methode verfügt. Sie muss nicht wissen, ob sie mit einem Car, einem Bicycle oder einem anderen Fahrzeugtyp arbeitet, den du später hinzufügen könntest.
Probier es selbst
package main
import (
"fmt"
)
// TODO: Erstelle eine PrintDescription-Funktion, die jeden Describer akzeptiert
// und das Ergebnis des Aufrufs ihrer Describe()-Methode ausgibt
func main() {
// Eingabe lesen
var carBrand string
var carModel string
var bicycleType string
var gears int
fmt.Scanln(&carBrand)
fmt.Scanln(&carModel)
fmt.Scanln(&bicycleType)
fmt.Scanln(&gears)
// TODO: Erstelle ein Car mit der Marke und dem Modell aus der Eingabe
// TODO: Erstelle ein Bicycle mit dem Typ und den Gängen aus der Eingabe
// TODO: Verwende PrintDescription, um die Beschreibung des Autos auszugeben
// TODO: Verwende PrintDescription, um die Beschreibung des Fahrrads auszugeben
}
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 in Go
Externe DateienGo-Workspace & ModulePackages & ImportsExportierte vs. nicht exportierte NamenEinführung in OOP mit GoStructs als KlassenMethoden für Structs definierenPointer- vs. Value-ReceiverStruct-InitialisierungKonstruktorfunktionenRückblick – Einfacher Taschenrechner4Schnittstellen
Einführung in SchnittstellenImplizite ImplementierungSchnittstelle als VertragLeere Schnittstelle (any)TypzusicherungTypwechselZusammensetzung von SchnittstellenStringer- und Error-SchnittstellenRückblick – Formenrechner7Kapselung
Exportierte vs. nicht exportierte FelderKapselung auf PaketebeneGetter- und Setter-MethodenInformationsverbergung in GoRückblick – Studierendendatensätze10Generics (Go 1.18+)
Einführung in GenericsTypparameterTypbeschränkungenGenerische StrukturenWorkaround für generische MethodenZusammenfassung – Generische Sammlung2Typen & Structs im Detail
Grundlegende & zusammengesetzte TypenBenutzerdefinierte TypdefinitionenStruct-TagsAnonyme StructsVerschachtelte StructsNullwerte & StandardwerteRückblick – Kontaktbuch5Komposition statt Vererbung
Warum Go keine Vererbung hatGrundlagen der Struct-EinbettungMethoden-PromotionMehrere Structs einbettenEinbettung vs. AggregationVerbergen eingebetteter MethodenRückblick – Mitarbeiterhierarchie8Fehlerbehandlung & OOP
Das Error-InterfaceBenutzerdefinierte FehlertypenError-Wrapping (fmt.Errorf)Sentinel-Fehlererrors.Is() und errors.As()Panic, Defer und RecoverRückblick – Dateiparser3Zeiger & Speicher
Grundlagen von Zeigern in GoZeiger auf StructsÜbergabe per Wert vs. ReferenzDie Funktion new()Garbage Collection in GoRückblick – Verkettete Liste erstellen6Polymorphismus in Go
Polymorphismus über InterfacesDuck-Typing in GoRegeln zur Interface-ErfüllungPolymorphe SammlungenDependency InjectionZusammenfassung – Zahlungsprozessor9Konkurrenz & OOP
Grundlagen der GoroutinesChannels & KommunikationGepufferte vs. ungepufferte ChannelsSelect-Anweisungsync.Mutex & sync.RWMutexsync.WaitGroupThread-sicheres Struct-DesignRückblick – Worker PoolÜbe selbstständig: Online-Go-Compiler