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!