Dalla domanda che fai sembra quasi che tu non abbia capito il pattern decorator.
L'esercizio peraltro è anche abbastanza semplice essendoci una sola classe concreta e due decorator. La classe concreta è quella che normalmente useresti come superclasse e i decorator sono quelle che normalemnte progetteresti come figlie. L'ereditarietà non va bene nel momento in cui c'è la possibilità di creare classi figlie le cui funzionalità non sono altro che la combinazione delle funzionalità di altre classi figlie.
In questo caso si cerca di isolare queste funzionalità in un interfaccia o una classe base.
Nel tuo caso la funzionalità comune è StampaInfo, la classe base è Persona. Percio bisogna creare un interfaccia (o classe base astratta) InfoPrinter che dichiari il metodo StampaInfo. InfoPrinter deve implementare la classe base persona.
Ora non ti resta che implementare due classi decorator (e non tre) Studente e Lavoratore. Entrambe ereditano da InfoPrinter ma poiche questa eredita da persona entrambe sono anche di tipo Persona. Internamente le due classi contengono un istanza dell' oggetto da decorare il tipo di quest'istanza è Persona.
La chiave di volta di tutto questo apparato sta nell'implementazione del metodo StampaInfo il quale chiamerà prima StampaInfo dell'oggetto interno e poi ci "attaccherà" il proprio comportamento.
Ti faccio un esempio standard che usa qualche attore in piu rispetto a quanto ti serve per questo specifico esercizio. In una gerarchia di classi, infatti, ci potrebbero essere piu classi da decorare invece che una sola (Persona).
Non provare a compilare è pseudocodice 
codice:
public abstract class PersonaAbstract
{
public abstract string StampaInfo();
}
public abstract class PersonaConcrete
{
public abstract string StampaInfo()
{
//stampa nome e cognome
}
}
public abstract class InfoPrinter extends PersonaAbstract
{
public abstract string StampaInfo();
}
public class Studente extends InfoPrinter
{
PersonaAbstract inner;
public Studente(PersonaAbstract persona)
{
this.inner = persona;
}
public string StampaInfo()
{
persona.StampaInfo() + "Corso: " + Corso;
}
}
public class Lavoratore extends InfoPrinter
{
PersonaAbstract inner;
public Lavoratore(PersonaAbstract persona)
{
this.inner = persona;
}
public string StampaInfo()
{
persona.StampaInfo() + "Lavoro: " + Lavoro;
}
}
e cosi si usano:
codice:
//creo una persona
PersonaAbstract studenteLavoratore = new PersonaConcrete();
//... inserisco nome e cognome
studenteLavoratore.Stampainfo(); // stampa nome e cognome
//lo trasformo in uno studente
studenteLavoratore = new Studente(studenteLavoratore);
//...inserisco i suoi dati da studente
studenteLavoratore.Stampainfo(); // stampa nome e cognome e i dati da studente
//lo trasformo in uno studente lavoratore
studenteLavoratore = new Lavoratore(studenteLavoratore);
//...inserisco i dati da lavoratore
studenteLavoratore.Stampainfo(); // stampa nome e cognome, i dati da studente e da lavoratore