Menu
Coddy logo textTech

Mascheramento dei metodi embedded

Fa parte della sezione Programmazione orientata agli oggetti del percorso GO di Coddy. Lezione 39 di 107.

A volte è necessario che la struct esterna fornisca una propria implementazione di un metodo già presente nel tipo incorporato. Questo si chiama shadowing e consente di sovrascrivere i metodi promossi con un comportamento personalizzato.

Quando definisci un metodo sulla struct esterna con lo stesso nome di un metodo incorporato, prevale il metodo esterno:

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!"
}

Ora, quando chiami Speak() su un Dog, viene usato il metodo esterno:

func main() {
    d := Dog{Animal: Animal{Name: "Rex"}, Breed: "Labrador"}
    
    fmt.Println(d.Speak())        // Woof! - Dog's method
    fmt.Println(d.Animal.Speak()) // Some sound - Animal's method
}

Il metodo incorporato non è scomparso. Puoi ancora accedervi esplicitamente tramite il nome del tipo incorporato. Questo schema è utile quando vuoi personalizzare il comportamento mantenendo disponibile l'implementazione originale, magari per richiamarla dal tuo metodo di override:

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

L'ombreggiamento ti consente di controllare quale comportamento viene esposto, mantenendo al contempo l'accesso all'originale tramite qualificazione esplicita.

challenge icon

Sfida

Facile

Costruiamo un sistema di notifiche in cui diversi canali di notifica possano personalizzare il modo in cui formattano e inviano i messaggi. Userai l'oscuramento dei metodi per consentire a canali specifici di sovrascrivere il comportamento predefinito, mantenendo comunque la possibilità di accedere all'implementazione originale quando necessario.

Organizzerai il codice in tre file:

  • base.go: crea una struct BaseNotification con i campi Title e Priority (entrambi stringhe). Aggiungi un metodo Format() string che restituisca la notifica in un formato standard: [Priority] Title.
  • channels.go: crea due tipi di canale di notifica che incorporano BaseNotification e oscurano il metodo Format con le proprie implementazioni:
    • EmailNotification con un campo Recipient. Il suo Format() dovrebbe restituire Email to [Recipient]: [Priority] Title
    • SlackNotification con un campo Channel. Il suo Format() dovrebbe chiamare il metodo incorporato BaseNotification.Format() e anteporre #[Channel]: al risultato
  • main.go: leggi i dettagli delle notifiche dall'input, crea entrambi i tipi di notifica e mostra l'oscuramento stampando:
    1. L'output formattato di EmailNotification (usando il suo metodo oscurato)
    2. Il formato di base di EmailNotification (chiamando esplicitamente il metodo incorporato)
    3. L'output formattato di SlackNotification (che usa internamente il metodo di base)

Verranno forniti i seguenti input:

  • Riga 1: titolo della notifica
  • Riga 2: livello di priorità
  • Riga 3: destinatario dell'email
  • Riga 4: nome del canale Slack

Ad esempio, dati Server Alert, HIGH, admin@company.com e ops-alerts, l'output dovrebbe essere:

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

Nota come EmailNotification sostituisca completamente la formattazione di base, mentre SlackNotification la arricchisca chiamando il metodo originale e aggiungendo il contesto del canale. Entrambi gli approcci dimostrano diversi modi di usare efficacemente l'oscuramento dei metodi.

Provalo tu

package main

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

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	
	// Leggi il titolo della notifica
	scanner.Scan()
	title := scanner.Text()
	
	// Leggi il livello di priorità
	scanner.Scan()
	priority := scanner.Text()
	
	// Leggi il destinatario dell'email
	scanner.Scan()
	recipient := scanner.Text()
	
	// Leggi il nome del canale Slack
	scanner.Scan()
	channel := scanner.Text()
	
	// TODO: Crea un'istanza di EmailNotification con la notifica di base, il titolo, la priorità e il destinatario
	
	// TODO: Crea un'istanza di SlackNotification con la notifica di base, il titolo, la priorità e il canale
	
	// TODO: Stampa l'output formattato di EmailNotification (usando il suo metodo che nasconde quello incorporato)
	
	// TODO: Stampa il formato di base di EmailNotification (chiamando esplicitamente il metodo incorporato)
	
	// TODO: Stampa l'output formattato di SlackNotification
	
	fmt.Println() // Segnaposto - rimuovere durante l'implementazione
}
quiz iconMettiti alla prova

Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.

Tutte le lezioni di Programmazione orientata agli oggetti

Esercitati da solo: Compilatore Go online