# Classe astratta

Una classe astratta, nella programmazione orientata agli oggetti, è una classe che definisce una interfaccia senza implementarla completamente. Questo serve come base di partenza per generare una o più classi specializzate aventi tutte la stessa interfaccia di base, le quali potranno poi essere utilizzate indifferentemente (ovvero in modo polimorfico) da applicazioni che conoscono l'interfaccia base della classe astratta.

## Caratteristiche

La classe astratta da sola non può essere istanziata, viene progettata soltanto per svolgere la funzione di classe base (chiamata a volte anche classe genitrice) e da cui le classi derivate (chiamate anche classi figlie) possono ereditare i metodi. Le classi astratte sono usate anche per rappresentare concetti ed entità astratte. 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.
Le classi astratte possono essere considerate come super-classi che contengono metodi astratti, progettate in modo che le sotto-classi che ereditano da esse ne "estenderanno" le funzionalità implementandone i metodi. Il comportamento definito da queste classi è "generico". Prima che una classe derivata da una classe astratta possa essere istanziata essa ne deve implementare tutti i metodi astratti.
Per sintetizzare, quando viene definita una classe astratta il programmatore deve tener presente che si tratta di una classe che non può essere istanziata direttamente; per fare ciò è necessario creare una classe derivata mediante l'ereditarietà. 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.
Al contrario, una classe concreta è una classe dalla quale possono essere create ("istanziate") entità chiamate "oggetti".
La maggior parte dei linguaggi di programmazione orientati agli oggetti consente al programmatore di specificare, con apposite parole chiave, quali classi sono astratte, impedendo in modo automatico che su di esse vengano istanziati oggetti (ad esempio Java usa la keyword abstract). Con questi accorgimenti il programmatore può concentrarsi sull'analisi e lo sviluppo del programma: l'implementazione effettiva delle funzionalità necessarie viene fatta nelle classi derivate che ereditano da quella astratta.

## Esempi
### C++

In C++ una funzione membro di una classe per la quale non viene fornita alcuna implementazione prende il nome di funzione virtuale pura, indicata esplicitamente concludendone la dichiarazione tramite la sintassi "= 0". Ad esempio:
Una classe è implicitamente considerata astratta se:
* dichiara almeno una funzione virtuale pura
* oppure eredita almeno una funzione virtuale pura da una superclasse senza a sua volta fornirne un'implementazione.

### Java

In Java sia i metodi astratti che le classi astratte sono indicati esplicitamente tramite la parola chiave abstract.
Una classe contenente almeno un metodo astratto è a sua volta astratta, e deve pertanto essere dichiarata come tale (l'assenza della parola chiave abstract causa un errore di compilazione). È d'altra parte possibile dichiarare una classe come astratta pur in assenza di metodi astratti: benché in tal caso la classe sia, da un punto di vista prettamente strutturale, completamente definita, il compilatore ne impedisce, come richiesto, l'istanziazione diretta.
Un caso particolare di classi astratte in Java sono le cosiddette interfacce, dichiarate tramite la parola chiave interface. Rispetto alle più generiche classi astratte, le interfacce devono soddisfare due ulteriori vincoli:
* non possono includere campi membro (e non prevedono pertanto alcun costruttore, non avendo uno stato interno da inizializzare);
* tutti i loro metodi sono implicitamente astratti (e non richiedono pertanto la dichiarazione abstract).