Qual è la differenza tra un'interfaccia e una classe astratta?

Qual è esattamente la differenza tra un'interfaccia e una classe astratta?

Soluzione

Interfacce

Un'interfaccia è un contratto: La persona che scrive l'interfaccia dice, "ehi, accetto che le cose abbiano questo aspetto", e la persona che usa l'interfaccia dice "OK, la classe che scrivo ha questo aspetto".

Un'interfaccia è un guscio vuoto. Ci sono solo le firme dei metodi, il che implica che i metodi non hanno un corpo. L'interfaccia non può fare nulla. È solo un modello.

Per esempio (pseudo codice):

linguaggio: java -->

// I say all motor vehicles should look like this:
interface MotorVehicle
{
    void run();

    int getFuel();
}

// My team mate complies and writes vehicle looking that way
class Car implements MotorVehicle
{

    int fuel;

    void run()
    {
        print("Wrroooooooom");
    }

    int getFuel()
    {
        return this.fuel;
    }
}

Implementare un'interfaccia consuma pochissima CPU, perché non è una classe, solo un mucchio di nomi, e quindi non c'è nessun costoso look-up da fare. E' ottimo quando è importante, come nei dispositivi embedded.


Classi astratte

Le classi astratte, a differenza delle interfacce, sono classi. Sono più costose da usare, perché c'è una ricerca da fare quando si eredita da loro.

Le classi astratte assomigliano molto alle interfacce, ma hanno qualcosa in più: Si può definire un comportamento per loro. Si tratta più di una persona che dice, "queste classi dovrebbero avere questo aspetto, e hanno questo in comune, quindi riempite gli spazi vuoti!".

Per esempio:

// I say all motor vehicles should look like this:
abstract class MotorVehicle
{

    int fuel;

    // They ALL have fuel, so lets implement this for everybody.
    int getFuel()
    {
         return this.fuel;
    }

    // That can be very different, force them to provide their
    // own implementation.
    abstract void run();
}

// My teammate complies and writes vehicle looking that way
class Car extends MotorVehicle
{
    void run()
    {
        print("Wrroooooooom");
    }
}

Implementazione

Mentre le classi astratte e le interfacce dovrebbero essere concetti diversi, le implementazioni rendono questa affermazione a volte non vera. A volte, non sono nemmeno quello che si pensa che siano.

In Java, questa regola è fortemente applicata, mentre in PHP, le interfacce sono classi astratte senza alcun metodo dichiarato.

In Python, le classi astratte sono più un trucco di programmazione che si può ottenere dal modulo ABC ed è in realtà usare metaclassi, e quindi classi. E le interfacce sono più legate alla tipizzazione delle anatre in questo linguaggio ed è un mix tra convenzioni e metodi speciali che chiamano i descrittori (i metodi _metodo\).

Come al solito con la programmazione, c'è teoria, pratica e pratica in un altro linguaggio :-)

Commentari (22)

Una spiegazione può essere trovata qui:

Una classe astratta è una classe che è solo parzialmente implementata dal programmatore. Può contenere uno o più metodi astratti. Un metodo astratto è semplicemente una definizione di funzione che serve a dire al programmatore che il metodo deve essere implementato in un figlio classe.

Un'interfaccia è simile ad una classe astratta classe; infatti le interfacce occupano lo stesso spazio dei nomi delle classi e delle classi astratte classi. Per questa ragione, non potete definire un'interfaccia con lo stesso nome di una classe. Un'interfaccia è una classe completamente classe astratta; nessuno dei suoi metodi sono implementati e invece di una classe sottoclasse da essa, si dice che implementare quell'interfaccia.

Comunque trovo questa spiegazione delle interfacce un po' confusa. Una definizione più comune è: *Un'interfaccia definisce un contratto che le classi implementanti devono soddisfare. Una definizione di interfaccia consiste nelle firme dei membri pubblici, senza alcun codice di implementazione.

Commentari (3)

Non è proprio la risposta alla domanda originale, ma una volta che hai la risposta alla differenza tra loro, entrerai nel dilemma del quando usarli: https://stackoverflow.com/questions/1231985/when-to-use-interfaces-or-abstract-classes-when-to-use-both

Ho una conoscenza limitata di OOP, ma vedere le interfacce come un equivalente di un aggettivo nella grammatica ha funzionato per me fino ad ora (correggimi se questo metodo è fasullo!). Per esempio, i nomi delle interfacce sono come attributi o capacità che si possono dare a una classe, e una classe può averne molte: ISerializable, ICountable, IList, ICacheable, IHappy, ...

Commentari (0)