Differenze tra classi astratte ed interfacce

Giorgio Borelli

quali sono le caratteristiche e le principali differenze tra le classi astratte e le interfacce nella programmazione orientata agli oggettiLe classi astratte e le interfacce sono due concetti fondamentali della programmazione orientata agli oggetti (OOP, Object Oriented Programming), a prescindere dal linguaggio usato, sia questo Java, C++ o C#. L'importanza di conoscere i concetti teorici che stanno alla base di questi due elementi, è fondamentale per un buon programmatore; capire la differenza tra classi astratte ed interfacce permette di valutare in modo corretto quando usare l'una e quando usare l'altra.

Sia le classi astratte che le interfacce non possono essere instanziate poichè al loro interno definiscono soltanto i metodi e le proprietà che dovranno essere implementate dalle classi che deriveranno da esse, rappresentano pertanto un modello, oserei dire un "template" per le classi che una volta derivate da esse ed instanziate ne implementeranno il comportamento.

Classi astratte ed interfacce, così simili tra loro, possono confondere le idee ai neo programmatori che per le prime volte si avvicinano a questi concetti ed al polimorfismo della OOP, ma sebbene le similitudini sono molte vi sono delle sottili ma fondamentali differenze concettuali che è bene avere chiare in mente, per capire quando usare una classe astratta e quando una interfaccia.

Passiamo a descrivere brevemente prima le classi astratte e poi le interfacce, dopodichè ne evidenzieremo le differenze concettuali e di programmazione. Sebbene questi concetti teorici esulano dal linguaggio ae oggetti usato, come sintassi per i nostri esempi faremo riferimento al linguaggio C#, che è quello che ci piace di più ;)

 

Le Classi Astratte

Una classe astratta è una classe che non può essere instanziata e che serve solo per essere derivata, definendo al suo interno metodi e proprietà tutti o in parte anch'essi astratti. Una classe astratta che implementa solo ed esclusivamente metodi e proprietà astratte viene detta classe astratta pura.

Per definire una classe astratta in C#, dobbiamo anteporre alla definizione della classe la keyword abstract, stessa cosa vale per la definizione di metodi e proprietà astratte, come possiamo vedere nell'esempio seguente:

public abstract class Mammifero {

    //metodo astratto
    public abstract GetModoCamminare();

    //proprietà astratta
    public abstract string Name { get; set; }
    ...
}

Le classi astratte permetto d'implementare il concetto di polimorfismo, uno dei capisaldi della programmazione orientata agli ogetti. Il polimorfismo consente di assegnare comportamenti differenti a instanze di classi differenti devivanti tutte dalla stessa classe base, in questo caso la classe astratta. Per implementare il polimorfismo però i metodi e le proprietà del tipo base devono essere dichiarati come astratti o virtuali, affinchè questi possano essere riscritti (override) dal tipo derivato che ne instanzierà un particolare oggetto differente da un'altro ma con caratteristiche simili poichè derivanti entrambi dalla stessa classe madre, che ne definisce i comportamenti comuni tramite le signature dei metodi astratti.

Nel nostro esempio abbiamo definito una classe astratta Mammifero con un metodo modo di camminare ed una proprietà per il nome, le possibili instanze potrebbero essere:

public class Uomo: Mammifero {

    //metodo astratto
    public override string GetModoCamminare();

    //proprietà astratta
    public override string Name { get; set; }
    ...
} 

Come notate, la classe uomo deriva da quella mammifero (classe astratta) e ne implementa i metodi e le proprietà astratte tramite override, per spiegare il concetto facciamo un banale esempio, la classe astratta definisce (ma non implementa) il metodo modo di camminare, nell'istanza della classe uomo questo metodo ritornerà bipede, mentre per un'istanza cane tornerebbe quadrupede, vedete il polimorfismo, a concetti comuni s'implementano comportamenti differenti.

Nota:  è bene precisare che tra metodi astratti e virtuali vi è una sostanziale differenza, i primi vengono solamente definiti nella classe astratta ed ognuno di esso deve essere necessariamente implementato nella classe derivata, i metodi virtuali possono invece essere anche implementati nella classe astratta e se questi non vengono riscritti (override) nella classe derivata, questa implementerà il metodo (virtuale) della classe astratta. Si definisce un metodo virtuale in C#, mettendo la keyword virtual prima della definizione del metodo stesso.

 

Le Interfacce

Le interfacce sono molto simili alle classi astratte, in quanto anch'essa definisce metodi e proprietà astratte. Nelle interfacce non troveremo l'implemetazione di alcun metodo o proprietà, come per le classi astratte pure, si dice che le interfacce stipulino un contratto con la classe derivata che le implementa.

Per definire un'interfaccia in C#, bisogna anteporre la keyword interface al nome dell'interfaccia stessa, inoltre gli access modifier per i membri non vengono specificati nelle interfacce. Proviamo ad es. a definire un'interfaccia che definisca un metodo che sarà comune a tutte le sue classi derivate:

public interface ICalc {

    //metodo dell'interfaccia
    public Count();

    ...
} 

In questo semplicissimo esempio abbiamo definito un solo metodo per l'interfaccia, ma queste possono definire non solo metodi, ma anche proprietà ed eventi.

Solitamente i nomi delle interfacce vengono preceduti da una i maiuscola proprio per identificarle immediatamente all'interno del codice e distinguerle dalle classi, per quanto riguarda la loro implementazione invece, questa è identica alle regole usate per l'ereditarietà tra le classi, quindi basta postporre i due punti ":" al nome della classe e scrivere di seguito il nome dell'interfaccia che si vuole implementare. Una prima differenza tra classi astratte ed interfacce, almeno in C# e Visual Basic, e che mentre per le classi non è ammessa l'ereditarietà multipla, ma soltanto quella singola, questo non è vero per le interfacce. Una classe derivata può implemetare più di una interfaccia contemporaneamente, basterà separare con una virgola i nomi delle interfacce che si vogliono implementare per quella classe. Ovviamente una classe può derivare contemporaneamente da una classe madre e da una o più interfacce basta separare i nomi dell'une e delle altre sempre con le virgole.

A differenza delle classi astratte per l'implementazione di una interfaccia non si rende necessario usare la keyword override, basterà implementare il metodo definito nella interfaccia.

 

Quando usare le classi astratte e quando le Interfacce

Come abbiamo visto, sia le classi astratte che le interfacce rappresentano un modello, un contratto che la classe derivata deve rispettare implementando i metodi e le proprietà definite nel tipo base, ma allora al di là delle piccole differenze di sintassi qual'è la sostanziale differenza tra classi astratte pure ed interfacce, come capire quando usare l'una e quando le altre?  La risposta migliore è a seconda del tipo di contratto che la classe derivata deve implementare col tipo base, le classi astratte pure definiscono un legame più forte con la classe derivata poichè ne rappresentano il tipo base definendone il comportamento comune (vedi l'es. della classe mammifero). Mentre le interfacce possono essere usate per definire un modello generico, che implementa un comportamento comune a classi di vario genere e natura, ad esempio il metodo calc dell'iiterfaccia ICalc potrebbe essere comune sia ad un'istanza di una classe calcolatrice che a quello di un'istanza punto geometrico.

 

Se mi permettete una definizione personale, direi che le classi astratte pure definiscono un contratto di tipo verticale (dedicato) con le instanze delle classi figlie, mentre le interfacce rappresentano di più un contratto di tipo orizzontale (generico) con gli oggetti che le implementeranno.

Categorie: C#

Tags: , ,

Commenti (14) -

Cosimo Meli
Cosimo Meli says:

Questo articolo mi è piaciuto davvero molto, ben fatto!
Per creare una classe che non deve poter essere istanziata, ovvero una collezione di metodi e costanti statici, in Java cosa conviene? Pensavo a una classe astratta statica, ma non so se effettivamente è la scelta più corretta dal punto di vista teorico.

Rispondi

Ciao Cosimo, grazie per il complimento sull'articolo, come sei magnanimo vuoi dire che gli altri non ti sono piaciuti tanto?

Per poter creare una classe che non può essere istanziata devi creare una Classe Statica, punto, un solo riferimento in memoria (la classe statica) condiviso nel suo scope di visibilità, la quale accede ai suoi metodi e proprietà statiche attraverso l'operatore punto; non crei l'oggetto, non usi il costruttore, la invochi così per com'è.

Non confondere Classi Astratte con Classi Statiche, vero è che non istanzi nemmeno la Classe Astratta, ma questa serve per definire un modello che sarà istanziato e personalizzato nelle classi figlie, mentre la Classe Statica la usi e come, addirittura la invochi direttamente, invece la Classe Astratta se non la fai ereditare non ti serve a nulla.

Per Capire quale tipo di Classe usare, bisogna fare un'analisi attenta dell'astrazione della realtà che intendi rappresentare, e fare le scelte più giuste per un'implementazione elegante, funzionale ed ottimizzata del codice OOP del tuo progetto.
Non centra il linguaggio che usi, Java, C# o chichessia, anche se puoi farlo, io difficilmente mischierei Classe Astratte con metodi statici, mai visto niente del genere. Mi viene da pensare che l'analisi del problema è stata fatta in modo errato e probabilmente esiste una soluzione più semplice.

La classe statica solitamente si usa per gestire degli aspetti comuni a tutto il software (o applicazione web), tipo impostazioni di configurazione, recuperare nome della connection string e simili, non la usi per astrarre la realta come invece fai con le Classi normali, la derivazione e gli altri aspetti della programmazione orientata agli ogetti.

Spero di essere stato chiaro, se hai ulteriori domande io sono qua, ciauz!

Rispondi

Buon articolo breve e chiaro.
Continuando sull'astrazione come costruire dipendenze  e quando inniettarle con i webform.

Rispondi

Ciao Davide, e grazie per il tuo intervento e per il complimento.

Tuttavia, non riesco a comprendere la tua domanda, puoi articolarla in maniera diversa, non riesco a coglierne il senso, grazie.

Rispondi

Dopo aver letto l'articolo ho le idee ancora più confuse di prima :-(

Rispondi

"Fuso e Confuso" come cantava Lelluccio, o ancora "Tu resta pure ma io vado via" come disse il cervello di Homer ad Homer.

Certi concetti, più astratti e teorici, possono risultare ostici e difficili da fare propri, in questi casi la messa in pratica può aiutare molto, permette di entrare nei meccanismi e negli ingranaggi della programmazione molto di più di quanto non faccia un articolo o delle pagine scritte.

Carlo prova con degli esempi, se vuoi invece chiedere qualcosa posta pure la tua domanda, vediamo se riusciamo ad esserti d'aiuto più di quanto non lo sia stato l'articolo, che ritengo comunque chiaro semplice avendo un minimo di basi di OOP.

Rispondi

Francesco
Francesco says:

Se vuoi un consiglio cerca su google classi astratte e interfacce e cerca esempi per esempio qui www.geeknews.it/...e-e-classi-astratte-in-php.html

Rispondi

Ok Francesco, grazie della segnalazione.

Rispondi

fabioraciti
fabioraciti says:

Concordo pienamente sulla tua ultima definizione finale per descrivere le differenze tra classe astratta pura e interfaccia della classe

Rispondi

Grazie Fabio, la tua approvazione alla mia personale definizione di  classi astratte ed interfacce avvalora il fatto che essa riassume e rende bene l'idea delle loro differenze.

Se vuoi aggiungere dell'altro su Classi Astratte ed Interfacce, saremo lieti di leggerti.

Rispondi

Semplice ed essenziale. ;)

Rispondi

Bello l'articolo ma mi tolga una curiosità..
Perchè devo vedere la pubblicità di alcune scarpe da donna in un blog che dovrebbe riguardare l'informatica?......
Io capisco l'esigenza di fare anche due soldi in un blog, ma almeno essere coerenti con gli argomenti trattati no?

Rispondi

Caro Davide,
Le donne (con le loro scarpe) c'entrano sempre, e non sto del tutto scherzando.

Premesso che potrei disattivare questi tipi di annunci pubblicitari (e lo farò poiché non coerenti con l'informatica come giustamente indica Lei), posso però dirle che probabilmente la pubblicità di scarpe da donna le è stata mostrata in base alla sua cronologia di navigazione. Deve sapere infatti che AdSense non mostra solo pubblicità contestuali all'argomento, ma spesso presenta annunci inerenti la recente cronologia di navigazione dell'utente, quindi dovrebbe essere Lei a spiegarmi come mai (forse) salta da siti potenzialmente vicini al mondo femminile ad uno tecnico-informatico?
Provi ad esempio a navigare su alcuni siti inerenti la medicina e la salute e poi torni qui, vedrà che compariranno dei banner attinenti.
Questo non è un meccanismo matematico, vi sono altri fattori che influenzano la comparsa della pubblicità, ma posso dirle che ha una grossa influenza.

La ringrazio per il suo intervento e per i complimenti, spero di vederLa commentare nuovamente su questo mio blog, chissà che non trovi anche delle belle scarpe da uomo, saluti Giorgio Smile.

Rispondi

Pingbacks and trackbacks (1)+

Aggiungi Commento

biuquote
Loading