Nella programmazione ad oggetti spesso puΓ² crearsi il dubbio sulla differenza tra unβinterfaccia e una classe astratta e sulle modalitΓ per cui sia necessario utilizzare una a discapito dellβaltra.
Vediamo per prima cosa cosa sono entrambe per poi fare delle considerazioni sul loro utilizzo.
1. Interfacce
Unβinterfaccia Γ¨ un tipo di dato (paragonabile ad una classe) con le seguenti caratteristiche:
- Risulta composta solo da metodi astratti;
- ogni metodo dichiarato in unβinterfaccia deve essere implementato nella sottoclasse;
- Non ha attributi e quindi non puΓ² avere uno stato;
- Permette lβereditarietΓ multipla, in quanto una classe puΓ² essere figlia di piΓΉ interfacce
Unβinterfaccia puΓ² essere vista come punto di incontro tra componenti simili che hanno una struttura interna diversa.
2. Classi astratte
Citando Wikipedia, la classe astratta da sola non puΓ² essere istanziata, viene progettata soltanto per svolgere la funzione di classe base e da cui le classi derivate possono ereditare i metodi. Le caratteristiche βincompleteβ della classe astratta vengono condivise da un gruppo di sotto-classi figlie, che vi aggiungono caratteristiche diverse, in modo da colmare le βlacuneβ della classe base astratta.
Una classe astratta possiede le seguenti caratteristiche:
- Non puΓ² essere istanziata;
- Contiene almeno un metodo astratto;
- PuΓ² avere attributi e quindi avere uno stato;
- Una classe puΓ² essere figlia di una sola classe astratta.
Questo processo di astrazione ha lo scopo di creare una struttura base che semplifica il processo di sviluppo del software o che indirizza la programmazione delle classi figlie.
Utilizzando una classe astratta Γ¨ possibile inoltre definire delle implementazioni di default di metodi nel caso in cui i figli non le implementino.
3. Classe astratta o interfaccia?
Quando definiamo una classe astratta stiamo definendo le caratteristiche generiche di un oggetto (cosa un oggetto Γ¨), che saranno implementate genericamente dalle classi figlie. Nel caso invece di unβinterfaccia definiamo ciΓ² che un oggetto puΓ² fare, e siamo conseguentemente obbligati a definire, nella classe figlia, le implementazioni a questa capacitΓ .
Quindi un oggetto Γ¨ solo di un tipo (puΓ² essere figlio di una sola classe astratta) ma puΓ² avere tante abilitΓ diverse (puΓ² ereditare da diverse interfacce).
Per esempio la classe string
(in C#) ha la seguente dichiarazione:
Come si puΓ² notare le interfacce indicano tutte le cose che questo oggetto puΓ² fare, le capacitΓ che deve implementare per poter essere definito string.
Usare una interfaccia quando voglio un contratto per chi implementa lβinterfaccia sul comportamento che questo deve avere. Una interfaccia Γ¨ un guscio vuoto, molto leggero a livello di CPU, che non puΓ² fare nulla, Γ¨ solo un pattern.
Le classi astratte sono effettivamente classi, possono sia definire dei comportamenti generici (metodi astratti) che un comportamento di default (metodi concreti).