Menu
Coddy logo textTech

Verbergen eingebetteter Methoden

Teil des Abschnitts Objektorientierte Programmierung der GO-Journey von Coddy. Lektion 39 von 107.

Manchmal muss die äußere Struktur eine eigene Implementierung einer Methode bereitstellen, die der eingebettete Typ bereits besitzt. Dies wird als Überschattung bezeichnet und ermöglicht es dir, promovierte Methoden mit einem benutzerdefinierten Verhalten zu überschreiben.

Wenn du eine Methode für die äußere Struktur mit demselben Namen wie eine eingebettete Methode definierst, hat die äußere Methode Vorrang:

type Animal struct {
    Name string
}

func (a Animal) Speak() string {
    return "Some sound"
}

type Dog struct {
    Animal
    Breed string
}

func (d Dog) Speak() string {
    return "Woof!"
}

Wenn du jetzt Speak() für einen Dog aufrufst, wird die äußere Methode verwendet:

func main() {
    d := Dog{Animal: Animal{Name: "Rex"}, Breed: "Labrador"}
    
    fmt.Println(d.Speak())        // Woof! - Methode von Dog
    fmt.Println(d.Animal.Speak()) // Irgendein Geräusch - Methode von Animal
}

Die eingebettete Methode ist nicht verschwunden. Du kannst weiterhin explizit über den Namen des eingebetteten Typs auf sie zugreifen. Dieses Muster ist nützlich, wenn du das Verhalten anpassen und gleichzeitig die ursprüngliche Implementierung verfügbar halten möchtest, etwa um sie innerhalb deiner überschreibenden Methode aufzurufen:

func (d Dog) Speak() string {
    return d.Animal.Speak() + " (but actually Woof!)"
}

Shadowing gibt dir die Kontrolle darüber, welches Verhalten offengelegt wird, während du über eine explizite Qualifizierung weiterhin auf das ursprüngliche Verhalten zugreifen kannst.

challenge icon

Aufgabe

Einfach

Wir erstellen ein Benachrichtigungssystem, in dem verschiedene Benachrichtigungskanäle anpassen können, wie sie Nachrichten formatieren und zustellen. Du verwendest Methoden-Shadowing, damit bestimmte Kanäle das Standardverhalten überschreiben können und bei Bedarf trotzdem auf die ursprüngliche Implementierung zugreifen können.

Du organisierst deinen Code über drei Dateien:

  • base.go: Erstelle eine BaseNotification-Struktur mit den Feldern Title und Priority (beide vom Typ String). Gib ihr eine Methode Format() string, die die Benachrichtigung in einem Standardformat zurückgibt: [Priority] Title.
  • channels.go: Erstelle zwei Typen für Benachrichtigungskanäle, die BaseNotification einbetten und die Methode Format mit eigenen Implementierungen überschreiben:
    • EmailNotification mit einem Feld Recipient. Die Methode Format() soll Email to [Recipient]: [Priority] Title zurückgeben.
    • SlackNotification mit einem Feld Channel. Die Methode Format() soll die eingebettete Methode BaseNotification.Format() aufrufen und dem Ergebnis #[Channel]: voranstellen.
  • main.go: Lies die Benachrichtigungsdetails aus der Eingabe, erstelle beide Benachrichtigungstypen und veranschauliche das Methoden-Shadowing, indem du Folgendes ausgibst:
    1. Die formatierte Ausgabe von EmailNotification (unter Verwendung seiner überschriebenen Methode)
    2. Das Basisformat von EmailNotification (durch explizites Aufrufen der eingebetteten Methode)
    3. Die formatierte Ausgabe von SlackNotification (die intern die Basismethode verwendet)

Die folgenden Eingaben werden bereitgestellt:

  • Zeile 1: Titel der Benachrichtigung
  • Zeile 2: Prioritätsstufe
  • Zeile 3: E-Mail-Empfänger
  • Zeile 4: Name des Slack-Kanals

Wenn beispielsweise Server Alert, HIGH, admin@company.com und ops-alerts angegeben werden, sollte deine Ausgabe wie folgt aussehen:

Email to admin@company.com: HIGH Server Alert
[HIGH] Server Alert
#ops-alerts: [HIGH] Server Alert

Beachte, wie EmailNotification die Formatierung der Basis vollständig ersetzt, während SlackNotification sie durch den Aufruf der ursprünglichen Methode und das Hinzufügen des Kanalkontexts erweitert. Beide Ansätze veranschaulichen unterschiedliche Möglichkeiten, Methoden-Shadowing effektiv einzusetzen.

Probier es selbst

package main

import (
	"bufio"
	"fmt"
	"os"
)

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	
	// Benachrichtigungstitel lesen
	scanner.Scan()
	title := scanner.Text()
	
	// Prioritätsstufe lesen
	scanner.Scan()
	priority := scanner.Text()
	
	// E-Mail-Empfänger lesen
	scanner.Scan()
	recipient := scanner.Text()
	
	// Slack-Kanalnamen lesen
	scanner.Scan()
	channel := scanner.Text()
	
	// TODO: Erstelle eine EmailNotification mit der Basis-Benachrichtigung, title, priority und recipient
	
	// TODO: Erstelle eine SlackNotification mit der Basis-Benachrichtigung, title, priority und channel
	
	// TODO: Gib die formatierte Ausgabe der EmailNotification aus (unter Verwendung ihrer überschatteten Methode)
	
	// TODO: Gib das Basisformat der EmailNotification aus (expliziter Aufruf der eingebetteten Methode)
	
	// TODO: Gib die formatierte Ausgabe der SlackNotification aus
	
	fmt.Println() // Platzhalter - bei Implementierung entfernen
}
quiz iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Objektorientierte Programmierung

Übe selbstständig: Online-Go-Compiler