Chi ha almeno una volta studiato la programmazione ad oggetti, saprà cos'è il Polimorfismo. Il termine polimorfismo indica la possibilità di definire metodi e proprietà con lo stesso nome, in modo che, ad esempio, una classe derivata (figlia) possa ridefinire un metodo della classe principale (padre).

public class Persona
{
//...
public virtual void StampaNome()
{
System.Console.WriteLine("Nome: " + nome + " " + cognome);
}
//...
}
{/codecitation}
{codecitation class="brush: c#; gutter: false;"}
public class Studente : Persona
{
//...
public override void StampaNome()
{
System.Console.WriteLine("Nome: " + nome + " " + cognome);
System.Console.WriteLine("Matricola: " + matricola);
}
//...
}
{/codecitation}
Il metodo StampaNome() è definito in entrambe le classi, ma ha un comportamento diverso, visto che in Studente viene stampato anche il numero di matricola.
A seconda che si dichiari un oggetto di tipo Persona oppure Studente, verrà richiamata la routine StampaNome() corrispondente. Per fare questo, abbiamo usato il polimorfismo: il metodo StampaNome() nella classe base è stato dichiarato usando la parola chiave virtual: con essa si indica che è possibile avere un'altra definizione per la stessa routine in una classe derivata.
In Studente, infatti, StampaNome() è stato definito specificando la parola chiave override: in questo modo si dice che tale funzione sovrascrive un metodo con lo stesso nome che è stato definito nella classe principale.
In alcuni casi un metodo più pulito è quello di, all'interno del metodo ridefinito, richiamare il metodo che si sta ridefinendo. Nel nostro esempio, il metodo StampaNome() della classe Studente potrebbe richiamare il metodo StampaNome() di Persona, che si occupa già di mostrare il nome e il cognome, limitandosi quindi a stampare solo le informazioni proprie di uno studente.
Per fare questo, si deve usare la parola chiave base, che, consente di avere accesso alla classe che si sta derivando; detto ciò, il metodo StampaNome() di Studente diventa:
{codecitation class="brush: c#; gutter: false;"}
public override void StampaNome()
{
base.StampaNome();
System.Console.WriteLine("Matricola: " + mMatricola);
}
{/codecitation}
In pratica, base.StampaMessaggio() richiama il metodo corrispondente nella classe principale.
Si può anche sfruttare il polimorfismo con altre tecniche, ovvero usando la parola chiave new, che nasconde una definizione della classe principale con lo stesso nome. Esempio:
{codecitation class="brush: c#; gutter: false;"}
public class Persona
{
//...
public void StampaNome()
{
System.Console.WriteLine("Nome: " + mNome + " " + mCognome);
}
//...
}
public class Studente : Persona {
//...
public new void StampaNome()
{
base.StampaNome();
System.Console.WriteLine("Matricola: " + mMatricola);
}
//...
}
{/codecitation}
Si può notare che nella classe principale la parola chiave virtual è sparita, mentre in Studente il metodo StampaNome() è preceduto da new.
La differenza principale tra le due tecniche è che usando new, è possibile ridefinire un metodo completatmente; al contrario del primo esempio dove, il metodo della classe derivata, deve avere lo stesso numero di argomenti e dello stesso tipo.

Facciamo il classico esempio con le classi Persona e Studente per capire il concetto di polimorfismo. Realizzeremo anche un metodo pubblico StampaNome() nella classe Persona, che stampi a video le informazioni sulla persona. Analogamente, anche la classe Studente ha il suo metodo StampaNome() che mostri, oltre alle informazioni sulla persona, anche quelle proprie di uno studente. Perciò dobbiamo definire i metodi nel modo seguente:
{codecitation class="brush: c#; gutter: false;"}public class Persona
{
//...
public virtual void StampaNome()
{
System.Console.WriteLine("Nome: " + nome + " " + cognome);
}
//...
}
{/codecitation}
{codecitation class="brush: c#; gutter: false;"}
public class Studente : Persona
{
//...
public override void StampaNome()
{
System.Console.WriteLine("Nome: " + nome + " " + cognome);
System.Console.WriteLine("Matricola: " + matricola);
}
//...
}
{/codecitation}
Il metodo StampaNome() è definito in entrambe le classi, ma ha un comportamento diverso, visto che in Studente viene stampato anche il numero di matricola.
A seconda che si dichiari un oggetto di tipo Persona oppure Studente, verrà richiamata la routine StampaNome() corrispondente. Per fare questo, abbiamo usato il polimorfismo: il metodo StampaNome() nella classe base è stato dichiarato usando la parola chiave virtual: con essa si indica che è possibile avere un'altra definizione per la stessa routine in una classe derivata.
In Studente, infatti, StampaNome() è stato definito specificando la parola chiave override: in questo modo si dice che tale funzione sovrascrive un metodo con lo stesso nome che è stato definito nella classe principale.
In alcuni casi un metodo più pulito è quello di, all'interno del metodo ridefinito, richiamare il metodo che si sta ridefinendo. Nel nostro esempio, il metodo StampaNome() della classe Studente potrebbe richiamare il metodo StampaNome() di Persona, che si occupa già di mostrare il nome e il cognome, limitandosi quindi a stampare solo le informazioni proprie di uno studente.
Per fare questo, si deve usare la parola chiave base, che, consente di avere accesso alla classe che si sta derivando; detto ciò, il metodo StampaNome() di Studente diventa:
{codecitation class="brush: c#; gutter: false;"}
public override void StampaNome()
{
base.StampaNome();
System.Console.WriteLine("Matricola: " + mMatricola);
}
{/codecitation}
In pratica, base.StampaMessaggio() richiama il metodo corrispondente nella classe principale.
Si può anche sfruttare il polimorfismo con altre tecniche, ovvero usando la parola chiave new, che nasconde una definizione della classe principale con lo stesso nome. Esempio:
{codecitation class="brush: c#; gutter: false;"}
public class Persona
{
//...
public void StampaNome()
{
System.Console.WriteLine("Nome: " + mNome + " " + mCognome);
}
//...
}
public class Studente : Persona {
//...
public new void StampaNome()
{
base.StampaNome();
System.Console.WriteLine("Matricola: " + mMatricola);
}
//...
}
{/codecitation}
Si può notare che nella classe principale la parola chiave virtual è sparita, mentre in Studente il metodo StampaNome() è preceduto da new.
La differenza principale tra le due tecniche è che usando new, è possibile ridefinire un metodo completatmente; al contrario del primo esempio dove, il metodo della classe derivata, deve avere lo stesso numero di argomenti e dello stesso tipo.
0 commenti:
Posta un commento