Das Folgende ist ein einfaches Beispiel für einen schnittstellenbasierten Polymorphismus, der zeigt, wie eine Schnittstelle verwendet wird, um das gemeinsame Verhalten mehrerer Strukturen unterschiedlicher Typen zu erreichen. Konkrete Beispiele sind wie folgt:
package main
import "fmt"
type Animal interface {
Speak() string
}
type Dog struct {
Name string
}
func (d Dog) Speak() string {
return "Woof!"
}
type Cat struct {
Name string
}
func (c Cat) Speak() string {
return "Meow!"
}
func main() {
animals := []Animal{
Dog{
Name: "Fido"}, Cat{
Name: "Whiskers"}}
for _, animal := range animals {
fmt.Println(animal.Speak())
}
}
In diesem Beispiel definieren wir eine Animal-Schnittstelle und implementieren dann zwei verschiedene Arten von Strukturen, nämlich Dog und Cat. Beide Strukturen implementieren die in der Animal-Schnittstelle definierte Speak-Methode. In der Hauptfunktion erstellen wir einen Animal-Slice, der zwei verschiedene Tierarten enthält, und durchlaufen den Slice, um die Speak-Methode jedes Tieres aufzurufen.
Diese Art von Polymorphismus bietet ein breites Spektrum an Verwendungsszenarien und ermöglicht es uns, allgemeinen Code zu schreiben, der verschiedene Objekttypen verarbeiten kann, ohne für jeden spezifischen Typ unterschiedlichen Code schreiben zu müssen. Dadurch wird der Code flexibler und wartbarer, da wir neue konkrete Typen hinzufügen können, ohne den vorhandenen Code zu ändern.
Die Implementierung von Polymorphismus mithilfe von Schnittstellen kann jedoch auch zu Leistungsproblemen führen, da Go zur Laufzeit eine Typprüfung der Schnittstellen erfordert. Wenn wir außerdem die Methoden der Struktur selbst verwenden müssen, müssen wir Typzusicherungen machen, um auf die Eigenschaften und Methoden der Struktur zuzugreifen. Daher müssen die Vor- und Nachteile sorgfältig abgewogen werden, wenn eine Schnittstelle entworfen oder verwendet wird.