Morpheusweb.it - Risorse per webmaster: script, ASP.NET, C#, Visual Basic .Net, tutorial, asp, javascript, css, php, html, java, ADO, VBScript, forms, frames, Active Server Pages, Dynamic HTML, database, gratis per webmaster e webdesigner

Ereditarietà e Polimorfismo C#

Ereditarietà



Ereditarietà ed Overwriting

I linguaggi orientati agli oggetti consentono l'ereditarietà dei tipi riferimento. Se un tipo eredita da un altro, ne prende tutti i membri. Ad un tipo si possono tuttavia aggiungere dei nuovi membri oppure riscriverne alcuni.

I tipi sono organizzati in una gerarchia.

Supponiamo di avere uno stack e di volerne contare gli elementi.
Potremmo riscrivere la classe con il metodo in più che esegue il conteggio, oppure utilizzare l’ereditarietà.

Stack<-Counting_Stack

Baso il nuovo tipo che mi serve sull’implementazione originale. I sottotipi (classi ereditate) possono avere dei sottotipi in più e ridefinire le funzioni virtuali.

Overwriting

Le classi possono ereditare i metodi dalle classi padri, ed utilizzarli senza problemi. A volte però vogliamo che una classe figlia si comporti in modo diverso dalla classe da cui eredita.
In questi casi possiamo “sovrascrivere” il metodo che ci interessa, nella nuova classe. In questo caso parliamo di “overwriting”.

Vediamo l'implementazione

using System;
namespace Sample
{
  public class Sample
  {
    public static void Main()
    {
      //start point
    }
    /// <summary>
    ///
Classe base
    /// </summary>

    private class Stack
    {
      //metodi della classe
      private Stack()
      {
        //costruttore base
      }
    }
    /// <summary>
    ///
Classe ereditata da Stack
    /// </summary>

    private class Counting_Stack : Stack
    {
      //metodi della classe
      public Counting_Stack() :base()
      {
        //prende le funzionalità del metodo della classe padre
      }
      //La funzionalità di conteggio elementi in più che volevamo
      public int contaElementi()
      {
        //implementazione
      }
    }
  }
}



Classi Astratte ed Interfacce

Alcune classi sono disegnate per non avere direttamente delle istanze, ma perchè altre classi possano ereditarvi.
Una classe è astratta quando non può avere delle istanze dirette.
Una interfaccia è una classe che contiene soltanto dei metodi astratti, tuttavia pure essendo una classe va dichiarata con la parola chiave 'interface' e non class.
Una classe può implementare anche più di una interfaccia, in quel caso deve definirne tutti i metodi e darne una implementazione.

classi abstract
Una dichiarata 'abstract' non può essere istanziata, è realizzata esclusivamente per consentire l'ereditarietà.

classi sealed
Una classe 'sealed' non consente ad altre classi di ereditare da essa.

Classi Nidificate

La classi vengono in genere specificate una indipendente dall'altra. E' comunque possibile dichiarare una classe all'interno di un'altra. in questo caso parliamo di classi nidificate.

Esempio:

public class clDBTools
{
  public class clDBConections
  {
    public clDBConections()
    {
      //costruttore;
    }
  }
  public clDBTools()
  {
    //costruttore;
  }
}



Polimorfismo ed Overriding

Supponiamo di avere due classi "Quadrato" e "Triangolo" che ereditano entrambe dalla classe padre "Figura".
Suppponiamo inoltreche in Figura ci sia un metodo per calcolare l'area, e questo metodo debba essere utilizzato anche dalle istanze di quadrato e triangolo.
Possiamo utilizzare l'overriding per richiamare il metodo corretto in base al tipo di classe di cui abbiamo istanziato un oggetto.

In parole povere se stiamo lavorato con un triangolo, utilizzaremo il metodo della classe triangolo, se invece stiamo lavorando con un quadrato utilizzaremo il metodo della classe quadrato.

Esempio

using System;
namespace Sample
{
  public class Sample
  {
    public static void Main()
    {
      //quando creiamo un triangolo, utilizziamo il costruttore ereditato da figura
      triangolo t = new triangolo(1,3);
      //richiamo il metodo della classe triangolo
      t.calcolaArea();
      quadrato q = new quadrato(1,3);
      q.calcolaArea();
    }
    private class Figura
    {
      //Fields dell'oggetto Figura
      //Vengono ereditati dagli oggetti figlio

      private double _Base;
      private double _Altezza;
      public double Base
      {
        get {return _Base;}
      }
      public double Altezza
      {
        get {return _Altezza;}
      }
      //metodi della classe
      public Figura(double Base, double Altezza)
      {
        this._Base = Base;
        this._Altezza = Altezza;
      }
      public virtual void calcolaArea()
      {
        //metodo della classe padre
      }
    }
    private class quadrato : Figura
    {
      public quadrato(double Base, double Altezza) :base(Base, Altezza)
      {
        Console.WriteLine("Questo è un quadrato");
        //prende le funzionalità del metodo della classe padre
        //per cui non necessitiamo di inizializzazione

      }
    public override void calcolaArea()
    {
      //metodo "overridden"
      Console.WriteLine("Area quadrato: " + Base*Altezza);
    }
  }
  private class triangolo : Figura
  {
    public triangolo(double Base, double Altezza) :base(Base, Altezza)
    {
      Console.WriteLine("Questo è un triangolo");
      //prende le funzionalità del metodo della classe padre
      //per cui non necessitiamo di inizializzazione

    }
    public override void calcolaArea()
    {
      //metodo "overridden"
      Console.WriteLine("Area triangolo: " + Base*Altezza/2);
      }
    }
  }
}


output

Questo è un triangolo
Area triangolo: 1,5
Questo è un quadrato
Area quadrato: 3

Stampa la pagina


 

Inizio pagina

risorse per webmaster