Sto lavorando al libro Head First Design Patterns e sono attualmente nel capitolo Decorator Pattern. Dal momento che gli esempi di libri sono scritti in Java, sto adattando il, a C # come vado.
Questo esempio simula un sistema di ordinazione di coffee shop. Esiste una classe base astratta per Beverage e sottoclassi per bevande specifiche (es: Espresso ). Le classi di decoratore sono usate per aggiungere condimenti e modifiche alle bevande. Esiste una classe astratta CondimentDecorator che deriva da Beverage e quindi sottoclassi come Mocha per i singoli decoratori. Sintesi con tutti i file: link
La mia domanda - nella classe base Beverage , la stringa descrittiva è impostata su "Bevanda sconosciuta". Il costruttore di una bevanda specifica lo imposta sul nome della bevanda, quindi se uso:
Beverage espresso = new Espresso();
Console.WriteLine($"{espresso.GetDescription()}");
Risponde a "Espresso". Ora, quando si usa il decoratore, il metodo GetDescription viene sovrascritto, nella classe Mocha aggiunge "Mocha" dopo la descrizione della bevanda.
public override string GetDescription()
{
return beverage.GetDescription() + " Mocha";
}
Se utilizzo il modificatore override in CondimentDecorator.cs:
public abstract override string GetDescription();
Funziona come previsto. Corro:
Beverage espresso = new Espresso();
Console.WriteLine($"{espresso.GetDescription()}"); // Espresso
espresso = new Mocha(espresso);
Console.WriteLine($"{espresso.GetDescription()}"); // Espresso Mocha
Tuttavia, se cambio il modificatore in new in CondimentDecorator.cs in questo modo:
public abstract new string GetDescription();
E esegui lo stesso codice, ottengo i seguenti risultati:
Beverage espresso = new Espresso();
Console.WriteLine($"{espresso.GetDescription()}"); // Espresso
espresso = new Mocha(espresso);
Console.WriteLine($"{espresso.GetDescription()}"); // Unknown beverage
Sono un po 'confuso perché questo accade ... dal momento che GetDescription viene chiamato in Mocha come questo ...
public override string GetDescription()
{
return beverage.GetDescription() + " Mocha";
}
... e la bevanda è un riferimento all'oggetto espresso originale, perché il codice non riprende la descrizione che è stata impostata quando è stata creata un'istanza di Espresso ? Per come ho capito, new nasconderebbe il metodo originale GetDescription nella classe base mentre override estenderebbe quel metodo. Non sono sicuro del motivo per cui ciò influisce sulla descrizione che il programma legge - la "bevanda sconosciuta" di Mocha , che ottiene quel valore dalla classe Beverage da cui deriva, o "Espresso" dell'oggetto bevanda I creato con la descrizione impostata nel costruttore.
Sono certo che sto solo fraintendendo qualcosa di basilare sull'ereditarietà e su come funzionano le parole chiave nuove e sovrascrivibili, se qualcuno può gettare un po 'di luce su questo lo apprezzerei!
Grazie!