Pagina personale di:
Carlo Vecchio
appunti di C#, R, SQL Server, ASP.NET, algoritmi, numeri
Vai ai contenuti

C# - Ereditarietà (Inheritance)

C#

Cos'è l'Ereditarietà
   •   In C# una classe può ereditare al massimo da una sola classe, ma può ereditare da una o più interfacce.
   •   Riguardo la classe derivata
, si dice che è una specializzazione della classe base.
   •   Quando di crea un oggetto della classe derivata, la classe base è istanziata prima della classe derivata e quindi il costruttore della classe base è eseguito prima del costruttore della classe derivata.
   •   Altri linguaggi di programmazione permettono l’eredità multipla delle classi risolvendo o gestendo in qualche modo le ambiguità che possono nascere; a questo proposito si veda il "Diamond Problem
".

Esempio con ereditarietà tra classi
   •   In questo esempio si ha la classe base ‘Persona’ e le due classi derivate ‘Dipendente’ e ‘Collaboratore’.
   •   È utilizzata la sintassi breve, sia nelle definizioni delle classi che nell’inizializzazione degli oggetti.
   •   Come si vede, le classi derivate estendono la classe base. La classe ‘Dipendende’ aggiunge le proprietà ‘Matricola’ e ‘Retribuzione’ mentre la classe ‘Collaboratore’ aggiunge la proprietà ‘Azienda’.

   class Program
   {
       
static void Main(string[] args)
       {
           
Persona p = new Persona() {
               Badge = 1,
               Cognome =
"Da Vinci",
               Nome =
"Leonardo" };
           
Dipendente d = new Dipendente() {
               Badge = 2, Cognome =
"Buonarroti",
               Nome =
"Michelangelo",
               Matricola = 1,
               Rettribuzione = 100
           };
           
Collaboratore c = new Collaboratore() {
               Badge = 3,
               Cognome =
"Vecellio",
               Nome =
"Tiziano",
               Azienda =
"Abc" };
       }       
   }

   
// Classe base.
   
class Persona
   {
       
public int Badge { get; set; }
       
public string Cognome { get; set; }
       
public string Nome { get; set; }
   }

   
// Prima classe derivata.
   
class Dipendente : Persona
   {
       
public int Matricola { get; set; }
       
public int Rettribuzione { get; set; }
   }

   
// Seconda classe derivata.
   
class Collaboratore : Persona
   {
       
public string Azienda { get; set; }
   }


   •   L’aggiunta di un metodo alla classe base, rende il metodo visibile a tutti gli oggetti delle tre classi.
   •   Per esempio, se si aggiunge il metodo ‘StampaInformazioni()’ alla classe base, si può utilizzare questo metodo su tutti e tre gli oggetti: ‘p’, ‘d’ e ‘c’.

   // Classe base.
   
class Persona
   {
       
public int Badge { get; set; }
       
public string Cognome { get; set; }
       
public string Nome { get; set; }

       
public void StampaInformazioni()
       {
           
Console.WriteLine("Badge: {0} Cognome: {1} Nome: {2} ", Badge.ToString(), Cognome, Nome);
       }
   }

   p.StampaInformazioni();
   d.StampaInformazioni();
   c.StampaInformazioni();

Hiding
   •   Le classi derivate possono avere metodi con lo stesso nome e la stessa firma dei corrispondenti metodi della classe base. Questo è l’hiding: un metodo della classe derivata che nasconde il metodo della classe base.
   •   Nell’esempio seguente, le classi derivate ‘Dipendente’ e ‘Collaboratore’ definiscono anch’esse il metodo ‘StampaInformazioni()’ già presente nella classe base. È importante la parola chiave ‘new
’ nell’instestazione di questi metodi, altrimenti il compilatore dà un warning.

   // Prima classe derivata.
   
class Dipendente : Persona
   {
       
public int Matricola { get; set; }
       
public int Rettribuzione { get; set; }

       
new public void StampaInformazioni()
       {
           
Console.WriteLine("Badge: {0} Cognome: {1} Nome: {2} Matricola: {3} Retribuzione: {4} ", Badge.ToString(), Cognome, Nome, Matricola, Rettribuzione);
       }
   }

   
// Seconda classe derivata.
   
class Collaboratore : Persona
   {
       
public string Azienda { get; set; }

       
new public void StampaInformazioni()
       {
           
Console.WriteLine("Badge: {0} Cognome: {1} Nome: {2} Azienda; {3} ", Badge.ToString(), Cognome, Nome, Azienda);
       }
   }


Override
   •   L’Override di un metodo è un concetto molto simile all’Hiding: un metodo di una classe derivata ha lo stesso nome e la stessa firma di un metodo della classe base. La classe base deve essere ‘virtual’.
   •   Nell’esempio seguente, le classi derivate ‘Dipendente’ e ‘Collaboratore’ definiscono anch’esse il metodo ‘StampaInformazioni()’ già presente nella classe base. È importante la parola chiave ‘override
’ nell’instestazione di questi metodi e la parola chiave ‘virtual’ nell’instestazione del metodo nella classe base, altrimenti il compilatore dà un errore.

   // Classe base.
   
class Persona
   {
       
public int Badge { get; set; }
       
public string Cognome { get; set; }
       
public string Nome { get; set; }

       
public virtual void StampaInformazioni()
       {
           
Console.WriteLine("Badge: {0} Cognome: {1} Nome: {2} ", Badge.ToString(), Cognome, Nome);
       }
   }

   
// Prima classe derivata.
   
class Dipendente : Persona
   {
       
public int Matricola { get; set; }
       
public int Rettribuzione { get; set; }

       
public override void StampaInformazioni()
       {
           
Console.WriteLine("Badge: {0} Cognome: {1} Nome: {2} Matricola: {3} Retribuzione: {4} ", Badge.ToString(), Cognome, Nome, Matricola, Rettribuzione);
       }
   }

   
// Seconda classe derivata.
   
class Collaboratore : Persona
   {
       
public string Azienda { get; set; }

       
public override void StampaInformazioni()
       {
           
Console.WriteLine("Badge: {0} Cognome: {1} Nome: {2} Azienda; {3} ", Badge.ToString(), Cognome, Nome, Azienda);
       }
   }

Differenza tra Hiding e Override
   •   Apparentemente l’Hiding e l’Override sono uguali: entrambi sovrascrivono il metodo della classe base con il metodo della classe derivata. In realtà c’è una differenza.
   •   Per vedere la differenza tra l’Hiding e l’Override bisogna ricorrere al Polimorfismo
. Esso permette di considerare un oggetto di una classe derivata, come oggetto della classe base.
   •   Se per esempio si ha la classe ‘Dipendente’ derivata dalla classe base ‘Persona’, l’oggetto ‘d’ di tipo ‘Dipendente’ può essere considerato di tipo ‘Persona’.

   class Program
   {
       
static void Main(string[] args)
       {
           
Dipendente d = new Dipendente() {
               Badge = 2, Cognome =
"Buonarroti",
               Nome =
"Michelangelo",
               Matricola = 1,
               Rettribuzione = 100
           };

           
Persona p = d;

           p.StampaInformazioni();
           
Console.ReadKey();
       }       
   }

   •   Il metodo ‘StampaInformazioni()’ è presente sia nella classe base, che nella classe derivata. Quale dei due metodi viene eseguito in un oggetto che ha cambiato forma?
   •   Se c’è l’Override del metodo (quindi metodo ‘virtual’ nella classe base e ‘override’ nella classe derivata) allora è eseguito il metodo della classe derivata. In altre parole si ‘scavalca’ l’implementazione di default della classe base.
   •   Se c’è l’Hiding del metodo (quindi metodo ‘new’ nella classe derivata) allora è eseguito il metodo della classe base.

© 2022 Carlo Vecchio
Torna ai contenuti