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


1753

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


96
Questa è una domanda di intervista estremamente comune. È sorprendente poiché una classe astratta viene raramente utilizzata nelle soluzioni rispetto ad altre cose. La tua domanda mi ha aiutato Safraz.
Catto,

5
Questa domanda potrebbe anche aiutare a capire il concetto di interfacce stackoverflow.com/q/8531292/1055241
gprathour

6
Ho rimosso il tag PHP da questa domanda, poiché quasi nessuna delle risposte è specifica della lingua e la domanda stessa non è specifica della lingua.
brice

2
indietro nel giorno in c ++ un'interfaccia è una classe base astratta pura con tutte le implementazioni del metodo = 0. Se un singolo metodo non era = 0, allora ha un'implementazione e la base astratta non è più pura e non è più un'interfaccia . Penso che il VMT abbia meno riferimenti indiretti quando l'ereditarietà multipla utilizza solo basi astratte pure, ma non ricordo più come appaiono, sono stati troppo lunghi.
Jim,

Risposte:


2255

interfacce

Un'interfaccia è un contratto : la persona che scrive l'interfaccia dice " ehi, accetto le cose che guardano in quel modo ", e la persona che usa l'interfaccia dice " OK, la classe che scrivo sembra così ".

Un'interfaccia è una shell vuota . Esistono solo le firme dei metodi, il che implica che i metodi non hanno un corpo. L'interfaccia non può fare nulla. È solo uno schema.

Ad esempio (pseudo codice):

// 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;
    }
}

L'implementazione di un'interfaccia consuma pochissima CPU, perché non è una classe, solo un mucchio di nomi, e quindi non c'è nessuna ricerca costosa da fare. È fantastico quando è importante, come nei dispositivi integrati.


Classi astratte

Le classi astratte, a differenza delle interfacce, sono classi. Sono più costosi 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ù: puoi definire un comportamento per loro. Si tratta più di una persona che dice " queste classi dovrebbero assomigliare a questo e hanno questo in comune, quindi riempi 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 e le interfacce astratte dovrebbero essere concetti diversi, le implementazioni rendono questa affermazione talvolta falsa. A volte, non sono nemmeno quello che pensi 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 puoi ottenere dal modulo ABC e in realtà utilizza metaclasse, e quindi le classi. E le interfacce sono più legate alla tipizzazione duck in questo linguaggio ed è un mix tra convenzioni e metodi speciali che chiamano descrittori (i metodi __method__).

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


6
Il punto chiave sulle interfacce non è tanto quello che dicono ciò che fa una classe, ma consentono agli oggetti che possono Wizzle di rendersi utili al codice che necessita di un Wizzler. Si noti che in molti casi né la persona che scrive ciò che può Wizzle, né la persona che ha bisogno di un Wizzler, sarà la persona che scrive l'interfaccia.
supercat

187
Non penso che il consumo di CPU sia il punto saliente delle interfacce.
Dan Lugg,

5
@ e-satis Potresti spiegare il tuo punto sull'utilizzo della CPU? Perché la classe astratta essendo una classe aumenta l'utilizzo della CPU? A che tipo di ricerca ti riferisci qui?
Geek,

36
@ e-satis Con Java 8, è possibile definire metodi predefiniti nelle interfacce che equivale ad avere metodi non astratti in classi astratte. Con questa aggiunta, non riesco più a vedere la vera differenza tra le classi astratte e l'interfaccia oltre al fatto che dovrei usare le interfacce perché le classi possono implementare più interfacce ma possono ereditare solo una classe
Ogen

23
Penso al confronto tra interfacee classdaHead First Java sia chiaro cheA class defines who you are, and an interface tells what roles you could play
LittleLittleQ

872

Le principali differenze tecniche tra una classe astratta e un'interfaccia sono:

  • Le classi astratte possono avere costanti, membri, matrici di metodi (metodi senza corpo) e metodi definiti , mentre le interfacce possono avere solo costanti e matrici di metodi .

  • Metodi e membri di una classe astratta possono essere definiti con qualsiasi visibilità , mentre tutti i metodi di un'interfaccia devono essere definiti come public(sono definiti pubblici per impostazione predefinita).

  • Quando si eredita una classe astratta, una classe figlio concreta deve definire i metodi astratti , mentre una classe astratta può estendere un'altra classe astratta e non è necessario definire metodi astratti dalla classe genitore.

  • Allo stesso modo, un'interfaccia che estende un'altra interfaccia non è responsabile dell'implementazione dei metodi dall'interfaccia genitore. Questo perché le interfacce non possono definire alcuna implementazione.

  • Una classe figlio può estendere solo una singola classe (astratta o concreta), mentre un'interfaccia può estendersi o una classe può implementare più altre interfacce .

  • Una classe figlio può definire metodi astratti con stessa visibilità o meno restrittiva , mentre una classe che implementa un'interfaccia deve definire i metodi con la stessa identica visibilità (pubblica).


123
penso che questa sia la risposta migliore perché evidenzia tutte le differenze chiave. un esempio non è davvero necessario.
Joshua K,

4
E normalmente con le classi è possibile creare un'istanza di un oggetto da esso a differenza delle classi astratte CANNOTda istanziare.
SASM,

Ho pensato che una classe che implementa l'interfaccia debba definire tutti i metodi nell'interfaccia?
Utente Jiazzy il

@Jiazzyuser Se una classe astratta implementa un'interfaccia, non è necessario definire effettivamente i metodi dell'interfaccia. Tale requisito può essere rinviato alle classi ereditarie / secondarie concrete. Tuttavia, una classe concreta deve implementare tutti i metodi di interfaccia che non sono implementati dalla sua classe genitore. Aggiungerò un esempio per illustrare questo punto.
Justin Johnson,

5
"Quando si eredita una classe astratta, la classe figlio deve definire i metodi astratti, mentre un'interfaccia può estendere un'altra interfaccia e i metodi non devono essere definiti." - Questo non è vero. Proprio come un'interfaccia può estendere un'interfaccia senza definire metodi, una classe astratta può ereditare una classe astratta senza definire metodi.
Nick

141

Un'interfaccia contiene solo la definizione / firma della funzionalità e se abbiamo alcune funzionalità comuni e firme comuni, allora dobbiamo usare una classe astratta. Usando una classe astratta, possiamo fornire sia il comportamento che la funzionalità contemporaneamente. Un altro sviluppatore che eredita la classe astratta può usare facilmente questa funzionalità, poiché avrebbe solo bisogno di riempire gli spazi vuoti.

inserisci qui la descrizione dell'immagine Preso da:

http://www.dotnetbull.com/2011/11/difference-between-abstract-class-and.html

http://www.dotnetbull.com/2011/11/what-is-abstract-class-in-c-net.html http://www.dotnetbull.com/2011/11/what-is-interface-in -c-net.html


17
Devi dire a quale lingua si applica ("La classe astratta non supporta l'ereditarietà multipla" è lungi dall'essere universalmente vera)
Ben Voigt

L'ultimo confronto è confuso come da tabella! I metodi nell'interfaccia non possono essere statici ma le variabili sono statiche finali I metodi implementati in classe astratta possono essere statici
realPK

8
Il membro dell'interfaccia deve essere statico finale. L'ultima affermazione è sbagliata.
Jawad Zeb,

Penso che "funzionalità" in questa risposta significhi "implementazione". Non sei sicuro di cosa significhi "comportamento", forse "firme"?
LarsH,

2
Qual è il linguaggio di programmazione targetizzato qui? C #?
Peter Mortensen,

80

Una spiegazione è disponibile qui: http://www.developer.com/lang/php/article.php/3604111/PHP-5-OOP-Interfaces-Abstract-Classes-and-the-Adapter-Pattern.htm

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 una classe figlio.

Un'interfaccia è simile a una classe astratta; infatti le interfacce occupano lo stesso spazio dei nomi delle classi e delle classi astratte. Per tale motivo, non è possibile definire un'interfaccia con lo stesso nome di una classe. Un'interfaccia è una classe completamente astratta; nessuno dei suoi metodi è implementato e invece di una sottoclasse di classe da esso, si dice che implementa tale interfaccia.

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


4
Questa è la risposta più corretta, poiché le interfacce PHP differiscono dalle altre lingue in quanto le interfacce PHP SONO classi astratte sotto il cofano, mentre le interfacce di altre lingue sono firme che le classi devono corrispondere. Si comportano allo stesso modo purché non vi siano errori.
Tor Valamo,

1
È vero, per PHP è la vera risposta migliore. Ma è più difficile ottenere dal BLOB di testo che da un semplice frammento.
e-satis

Dalle definizioni fornite, sembrano uguali tranne un dettaglio: e l'interfaccia è astratta al 100%, mentre una classe astratta è parzialmente astratta e può avere alcune implementazioni di metodo (forse tutti i metodi possono avere implementazioni?).
jww

41

Non voglio evidenziare le differenze, che sono già state dette in molte risposte (per quanto riguarda i modificatori finali statici pubblici per le variabili nell'interfaccia e il supporto per metodi privati ​​e protetti in classi astratte)

In parole semplici, vorrei dire:

interfaccia: per implementare un contratto da più oggetti non correlati

classe astratta: per implementare lo stesso o diverso comportamento tra più oggetti correlati

Dalla documentazione di Oracle

Prendi in considerazione l'uso di classi astratte se:

  1. Vuoi condividere il codice tra diverse classi strettamente correlate.
  2. Ti aspetti che le classi che estendono la tua classe astratta abbiano molti metodi o campi comuni o che richiedano modificatori di accesso diversi da quelli pubblici (come protetti e privati).
  3. Si desidera dichiarare campi non statici o non finali.

Prendi in considerazione l'utilizzo di interfacce se:

  1. Ti aspetti che le classi non correlate implementino la tua interfaccia. Ad esempio, molti oggetti non correlati possono implementare l' Serializableinterfaccia.
  2. Vuoi specificare il comportamento di un particolare tipo di dati, ma non preoccuparti di chi lo implementa.
  3. Vuoi sfruttare l'ereditarietà multipla di tipo.

la classe astratta stabilisce "è una" relazione con classi concrete. l'interfaccia fornisce "ha una" capacità per le classi.

Se stai cercando Javacome linguaggio di programmazione, ecco alcuni altri aggiornamenti:

Java 8 ha ridotto il divario tra interfacee le abstractclassi in una certa misura fornendo una defaultfunzione di metodo. Un'interfaccia non ha un'implementazione per un metodo non è più valido ora.

Fare riferimento a questa pagina di documentazione per maggiori dettagli.

Dai un'occhiata a questa domanda SE per esempi di codice per capire meglio.

Come avrei dovuto spiegare la differenza tra un'interfaccia e una classe astratta?


38

Alcune differenze importanti:

Sotto forma di una tabella:

Differenza

Come affermato da Joe da javapapers :

1.La differenza principale è che i metodi di un'interfaccia Java sono implicitamente astratti e non possono avere implementazioni. Una classe astratta Java può avere metodi di istanza che implementano un comportamento predefinito.

2. I variabili dichiarati in un'interfaccia Java sono di default final. Una classe astratta può contenere variabili non finali.

3. I membri di un'interfaccia Java sono pubblici per impostazione predefinita. Una classe astratta Java può avere i soliti gusti dei membri della classe come privati, protetti, ecc.

4. L'interfaccia Java dovrebbe essere implementata usando la parola chiave "implementa"; Una classe astratta Java dovrebbe essere estesa usando la parola chiave "extends".

5. Un'interfaccia può estendere solo un'altra interfaccia Java, una classe astratta può estendere un'altra classe Java e implementare più interfacce Java.

6. Una classe Java può implementare più interfacce ma può estendere solo una classe astratta.

7. L'interfaccia è assolutamente astratta e non può essere istanziata; Anche una classe astratta Java non può essere istanziata, ma può essere invocata se esiste un main ().

8. In confronto con le classi astratte di Java, le interfacce Java sono lente in quanto richiedono un'ulteriore indiretta.


3
Ho modificato la tua risposta per fornire l'attribuzione corretta. Non puoi semplicemente rilasciare un link in fondo alla tua risposta. Devi citare anche tutta la lingua che è stata copiata da un'altra fonte. Inoltre, se quella tabella è stata disegnata da qualche parte, dovresti indicare chiaramente da dove proviene.
Brad Larson

Si prega di citare anche per C ++ .. anche se non esiste una parola chiave "interfaccia" in C ++ in quanto tale, ma è anche un Cn comunemente richiesto Q ++ regd.
Raccoglitore

@cbinder: non esiste una parola chiave "interfaccia" in c ++. Per la differenza in c ++, consultare 1. tutorialspoint.com/cplusplus/cpp_interfaces.htm 2. tutorialspoint.com/cplusplus/cpp_interfaces.htm
softmage99

@MageshBabu Forse la definizione di una funzione in una classe che contiene una funzione virtuale pura la rende una classe astratta piuttosto che l'interfaccia
cbinder

2
Con Java 8, le differenze sono meno adesso. Controlla le differenze aggiornate qui: journaldev.com/1607/…
Pankaj,

31

Il punto principale è che:

  • L'estratto è orientato agli oggetti . Offre i dati di base che un 'oggetto' dovrebbe avere e / o funzioni che dovrebbe essere in grado di fare. Si occupa delle caratteristiche di base dell'oggetto: cosa ha e cosa può fare. Quindi gli oggetti che ereditano dalla stessa classe astratta condividono le caratteristiche di base (generalizzazione).
  • L'interfaccia è orientata alla funzionalità . Definisce le funzionalità che un oggetto dovrebbe avere. Indipendentemente dall'oggetto, fintanto che può fare queste funzionalità, che sono definite nell'interfaccia, va bene. Ignora tutto il resto. Un oggetto / classe può contenere diverse (gruppi di) funzionalità; quindi è possibile per una classe implementare più interfacce.

Grazie ora stiamo arrivando da qualche parte con una buona risposta di alto livello. Divertente quanto in profondità nei commenti devi andare per trovare una risposta più comprensiva.
Andrew,

1
Le altre risposte sono troppo tecniche. Questo sta andando verso quella che riterrei una risposta "giusta". L'intero punto di OOP è la semantica, e se una classe annidata privata di getter pubblici venga invocata attraverso ricerche costose della CPU è praticamente irrilevante qui
Sentinel

26

Quando si desidera fornire un comportamento polimorfico in una gerarchia ereditaria, utilizzare le classi astratte.

Quando si desidera un comportamento polimorfico per le classi completamente non correlate, utilizzare un'interfaccia.


24

Sto costruendo un edificio di 300 piani

Il progetto dell'edificio interfaccia

  • Ad esempio, Servlet (I)

Edificio costruito fino a 200 piani - parzialmente completato --- astratto

  • Implementazione parziale, ad esempio servlet generico e HTTP

Costruzione di edifici completata - calcestruzzo

  • Completa implementazione, ad esempio, proprio servlet

Interfaccia

  • Non sappiamo nulla dell'implementazione, solo dei requisiti. Possiamo scegliere un'interfaccia.
  • Ogni metodo è pubblico e astratto per impostazione predefinita
  • È una classe astratta pura al 100%
  • Se dichiariamo pubblico non possiamo dichiarare privato e protetto
  • Se dichiariamo astratto non possiamo dichiarare finale, statico, sincronizzato, strictfp e nativo
  • Ogni interfaccia ha pubblico, statico e finale
  • La serializzazione e il transitorio non sono applicabili, poiché non è possibile creare un'istanza per l'interfaccia in
  • Non volatile perché è definitivo
  • Ogni variabile è statica
  • Quando dichiariamo una variabile all'interno di un'interfaccia, dobbiamo inizializzare le variabili durante la dichiarazione
  • Istanza e blocco statico non consentiti

Astratto

  • Implementazione parziale
  • Ha un metodo astratto. Un'aggiunta, utilizza calcestruzzo
  • Nessuna restrizione per i modificatori del metodo di classe astratta
  • Nessuna restrizione per i modificatori di variabili di classe astratte
  • Non possiamo dichiarare altri modificatori tranne l'astratto
  • Nessuna restrizione per inizializzare le variabili

Tratto dal sito DurgaJobs


Una classe astratta può avere un costruttore
vimal krishna,

4
Non sono completamente d'accordo con questo punto di vista. Il progetto è un concetto completamente diverso da "interfaccia". Il modello è più analogo a un modello statico o a una specifica di progetto per un'implementazione specifica. È più vicino alla "classe", poiché il progetto può essere istanziato più volte attraverso il suo costruttore, ma anche questo non è abbastanza vicino in quanto la "classe" contiene anche le specifiche su come costruire (il ctor) e i mezzi per fare così. L'interfaccia come concetto ha lo scopo di rappresentare alcuni comportamenti, come Riscaldamento / Raffreddamento, che possono essere applicati ad una serie di cose, ad esempio: edifici, forni, ecc.
Sentinel,

18

Lavoriamo di nuovo su questa domanda:

La prima cosa da farti sapere è che 1/1 e 1 * 1 danno lo stesso risultato, ma ciò non significa che la moltiplicazione e la divisione siano uguali. Ovviamente, intrattengono buoni rapporti, ma attenzione entrambi sono diversi.

Indicherò le principali differenze e il resto è già stato spiegato:

Le classi astratte sono utili per modellare una gerarchia di classi. A prima vista di ogni esigenza, siamo in parte chiari su cosa esattamente deve essere costruito, ma sappiamo cosa costruire. E quindi le tue classi astratte sono le tue classi di base.

Le interfacce sono utili per far sapere ad altre gerarchie o classi che cosa sono in grado di fare. E quando dici che sono capace di qualcosa, devi avere quella capacità. Le interfacce contrassegneranno come obbligatorio per una classe implementare le stesse funzionalità.


2
Buona risposta, ma la metafora della matematica è inutile e mi ha fatto sprecare all'incirca una quantità equivalente di tempo leggendola mentre scrivevo questo commento. Ora moltiplicalo per tutte le altre persone che hanno letto questa domanda.
Andrew,

"la metafora della matematica è inutile", perché la pensi così?
Dhananjay,

12

In realtà è piuttosto semplice.

Puoi pensare a un'interfaccia come a una classe alla quale è permesso avere solo metodi astratti e nient'altro.

Quindi un'interfaccia può solo "dichiarare" e non definire il comportamento che si desidera che abbia la classe.

Una classe astratta ti permette sia di dichiarare (usando metodi astratti) sia di definire (usando implementazioni di metodo complete) il comportamento che vuoi che abbia la classe.

E una classe regolare ti consente solo di definire, non dichiarare, il comportamento / le azioni che vuoi che la classe abbia.

Un'ultima cosa,

In Java, puoi implementare più interfacce, ma puoi estenderne solo una (Classe o Classe astratta) ...

Ciò significa che l'ereditarietà di un comportamento definito è limitata per consentirne solo uno per classe ... vale a dire se si desidera una classe che incapsuli il comportamento delle classi A, B e C, è necessario effettuare le seguenti operazioni: La classe A estende B, la classe C estende A .. è un po 'un modo per avere eredità multipla ...

Le interfacce invece, potresti semplicemente fare: l'interfaccia C implementa A, B

Quindi in effetti Java supporta l'ereditarietà multipla solo nel "comportamento dichiarato", cioè le interfacce, e solo l'ereditarietà singola con un comportamento definito ... a meno che tu non faccia il giro nel modo che ho descritto ...

Spero che abbia senso.


11

Il confronto tra interfaccia e classe astratta è errato. Dovrebbero esserci invece altri due confronti: 1) interfaccia vs. classe e 2) abstract vs. classe finale .

Interfaccia vs classe

Interfaccia è un contratto tra due oggetti. Ad esempio, sono un postino e sei un pacchetto da consegnare. Mi aspetto che tu conosca il tuo indirizzo di consegna. Quando qualcuno mi dà un pacco, deve conoscere il suo indirizzo di consegna:

interface Package {
  String address();
}

La classe è un gruppo di oggetti che obbediscono al contratto. Ad esempio, sono un box del gruppo "Box" e obbedisco al contratto richiesto dal Postino. Allo stesso tempo obbedisco ad altri contratti:

class Box implements Package, Property {
  @Override
  String address() {
    return "5th Street, New York, NY";
  }
  @Override
  Human owner() {
    // this method is part of another contract
  }
}

Estratto vs finale

La classe astratta è un gruppo di oggetti incompleti. Non possono essere utilizzati perché mancano alcune parti. Ad esempio, sono una casella astratta compatibile con GPS: so come controllare la mia posizione sulla mappa:

abstract class GpsBox implements Package {
  @Override
  public abstract String address();
  protected Coordinates whereAmI() {
    // connect to GPS and return my current position
  }
}

Questa classe, se ereditata / estesa da un'altra classe, può essere molto utile. Ma da solo - è inutile, dal momento che non può avere oggetti. Le classi astratte possono essere elementi di costruzione delle classi finali.

La classe finale è un gruppo di oggetti completi, che possono essere utilizzati, ma non possono essere modificati. Sanno esattamente come lavorare e cosa fare. Ad esempio, sono una scatola che va sempre all'indirizzo specificato durante la sua costruzione:

final class DirectBox implements Package {
  private final String to;
  public DirectBox(String addr) {
    this.to = addr;
  }
  @Override
  public String address() {
    return this.to;
  }
}

Nella maggior parte dei linguaggi, come Java o C ++, è possibile avere solo una classe , né astratta né definitiva. Tale classe può essere ereditata e può essere istanziata. Tuttavia, non penso che ciò sia strettamente in linea con il paradigma orientato agli oggetti.

Ancora una volta, il confronto delle interfacce con le classi astratte non è corretto.


9

In breve, le differenze sono le seguenti:

Differenze sintattiche tra interfaccia e classe astratta :

  1. Metodi e membri di una classe astratta possono avere qualsiasi visibilità. Tutti i metodi di un'interfaccia devono essere pubblici . // Non è più valido da Java 9
  2. Una classe figlio concreta di una Classe astratta deve definire tutti i metodi astratti. Una classe figlio astratta può avere metodi astratti. Un'interfaccia che estende un'altra interfaccia non deve fornire un'implementazione predefinita per i metodi ereditati dall'interfaccia padre.
  3. Una classe figlio può estendere una sola classe. un interfaccia può estendere più interfacce. Una classe può implementare più interfacce.
  4. Una classe figlio può definire metodi astratti con la stessa visibilità o meno restrittiva, mentre la classe che implementa un'interfaccia deve definire tutti i metodi dell'interfaccia come pubblici.
  5. Le classi astratte possono avere costruttori ma non interfacce .
  6. Le interfacce da Java 9 hanno metodi statici privati.

In Interfaces ora:

public static- supportato
public abstract- supportato
public default- supportato
private static- supportato
private abstract- errore di
private defaultcompilazione
private- errore di compilazione - supportato


8

L'unica differenza è che si può partecipare all'eredità multipla e altri no.

La definizione di un'interfaccia è cambiata nel tempo. Pensi che un'interfaccia abbia solo dichiarazioni di metodi e siano solo contratti? Che dire delle variabili finali statiche e delle definizioni predefinite dopo Java 8?

Le interfacce sono state introdotte a Java a causa del problema del diamante con eredità multipla ed è quello che intendono effettivamente fare.

Le interfacce sono i costrutti che sono stati creati per far fronte al problema dell'ereditarietà multipla e possono avere metodi astratti, definizioni predefinite e variabili finali statiche.

Vedi Perché Java consente le variabili finali statiche nelle interfacce quando sono intese solo come contratti? .


1
Sebbene questa sia una differenza importante , questa non è l'unica differenza.
Govind Parmar,

7

Interfaccia: gira (gira a sinistra, gira a destra.)

Classe astratta: ruota.

Classe: Volante, deriva dalla ruota, espone la curva dell'interfaccia

Uno è per categorizzare il comportamento che può essere offerto attraverso una vasta gamma di cose, l'altro è per modellare un'ontologia delle cose.


6

Se hai alcuni metodi comuni che possono essere utilizzati da più classi, scegli le classi astratte. Altrimenti, se vuoi che le classi seguano un modello definito, vai alle interfacce.

Gli esempi seguenti lo dimostrano.

Classe astratta in Java:

abstract class animals
{
    // They all love to eat. So let's implement them for everybody
    void eat()
    {
        System.out.println("Eating...");
    }
    // The make different sounds. They will provide their own implementation.
    abstract void sound();
}

class dog extends animals
{
    void sound()
    {
        System.out.println("Woof Woof");
    }
}

class cat extends animals
{
    void sound()
    {
        System.out.println("Meoww");
    }
}

Di seguito è riportata un'implementazione dell'interfaccia in Java:

interface Shape
{
    void display();
    double area();
}

class Rectangle implements Shape 
{
    int length, width;
    Rectangle(int length, int width)
    {
        this.length = length;
        this.width = width;
    }
    @Override
    public void display() 
    {
        System.out.println("****\n* *\n* *\n****"); 
    }
    @Override
    public double area() 
    {
        return (double)(length*width);
    }
} 

class Circle implements Shape 
{
    double pi = 3.14;
    int radius;
    Circle(int radius)
    {
        this.radius = radius;
    }
    @Override
    public void display() 
    {
        System.out.println("O"); // :P
    }
    @Override
    public double area() 
    { 
        return (double)((pi*radius*radius)/2);
    }
}

Alcuni punti chiave importanti in breve:

  1. Le variabili dichiarate nell'interfaccia Java sono di default final. Le classi astratte possono avere variabili non finali.

  2. Le variabili dichiarate nell'interfaccia Java sono di default statiche. Le classi astratte possono avere variabili non statiche.

  3. I membri di un'interfaccia Java sono pubblici per impostazione predefinita. Una classe astratta Java può avere i soliti gusti dei membri della classe come privati, protetti, ecc.


4

Molti sviluppatori junior commettono l'errore di pensare a interfacce, classi astratte e concrete come lievi variazioni della stessa cosa e scelgono una di esse puramente per motivi tecnici: ho bisogno dell'eredità multipla? Ho bisogno di un posto per mettere metodi comuni? Devo preoccuparmi di qualcosa di diverso da una lezione concreta? Questo è sbagliato e nascosto in queste domande c'è il problema principale: "I" . Quando scrivi il codice per te stesso, raramente pensi ad altri sviluppatori presenti o futuri che lavorano su o con il tuo codice.

Le interfacce e le classi astratte, sebbene apparentemente simili dal punto di vista tecnico, hanno significati e scopi completamente diversi.

Sommario

  1. Un'interfaccia definisce un contratto che alcune implementazioni realizzeranno per te .

  2. Una classe astratta fornisce un comportamento predefinito che la tua implementazione può riutilizzare.

Riepilogo alternativo

  1. Un'interfaccia serve a definire le API pubbliche
  2. Una classe astratta è per uso interno e per la definizione di SPI

Sull'importanza di nascondere i dettagli di attuazione

Una classe concreta fa il vero lavoro, in un modo molto specifico. Ad esempio, un ArrayListutilizza un'area contigua di memoria per memorizzare un elenco di oggetti in modo compatto che offre un accesso casuale rapido, iterazione e modifiche sul posto, ma è terribile per inserimenti, eliminazioni e occasionalmente anche aggiunte; nel frattempo, a LinkedListutilizza nodi a doppio collegamento per memorizzare un elenco di oggetti, che offre invece iterazione rapida, modifiche sul posto e inserimento / eliminazione / aggiunta, ma è terribile in caso di accesso casuale. Questi due tipi di elenchi sono ottimizzati per diversi casi d'uso e conta molto come li utilizzerai. Quando stai cercando di spremere le prestazioni da un elenco con cui interagisci pesantemente e quando scegli il tipo di elenco dipende da te, dovresti scegliere con cura quale stai istanziando.

D'altra parte, gli utenti di alto livello di un elenco non si preoccupano davvero di come sia effettivamente implementato e dovrebbero essere isolati da questi dettagli. Immaginiamo che Java non esponga l' Listinterfaccia, ma abbia solo una Listclasse concreta che è in realtà ciò che LinkedListè in questo momento. Tutti gli sviluppatori Java avrebbero adattato il proprio codice per adattarlo ai dettagli dell'implementazione: evitare l'accesso casuale, aggiungere una cache per accelerare l'accesso o semplicemente reimplementare ArrayListda soli, anche se sarebbe incompatibile con tutto l'altro codice che funziona effettivamente conList solo . Sarebbe terribile ... Ma ora immagina che i maestri Java si rendano davvero conto che un elenco collegato è terribile per la maggior parte dei casi d'uso reali, e hanno deciso di passare a un elenco di array solo per loroListclasse disponibile. Ciò influenzerebbe le prestazioni di ogni programma Java nel mondo e le persone non ne sarebbero contente. E il principale colpevole è che i dettagli di implementazione erano disponibili e gli sviluppatori hanno ipotizzato che quei dettagli fossero un contratto permanente su cui poter contare. Ecco perché è importante nascondere i dettagli dell'implementazione e definire solo un contratto astratto. Questo è lo scopo di un'interfaccia: definire quale tipo di input accetta un metodo e quale tipo di output è previsto, senza esporre tutte le viscere che inducono i programmatori a modificare il loro codice per adattarlo ai dettagli interni che potrebbero cambiare con qualsiasi aggiornamento futuro .

Una classe astratta è nel mezzo tra interfacce e classi concrete. Dovrebbe aiutare le implementazioni a condividere codice comune o noioso. Ad esempio, AbstractCollectionfornisce implementazioni di isEmptybase in base alla dimensione è 0, containscome iterare e confrontare, addAllcome ripetuto adde così via. Ciò consente alle implementazioni di concentrarsi sulle parti cruciali che le differenziano: come archiviare e recuperare i dati.

API contro SPI

Le interfacce sono gateway a bassa coesione tra diverse parti del codice. Consentono alle biblioteche di esistere e di evolversi senza interrompere tutti gli utenti delle biblioteche quando qualcosa cambia internamente. Si chiama Application Programming Interface , non Application Programming Classes. Su scala ridotta, consentono inoltre a più sviluppatori di collaborare con successo a progetti su larga scala, separando i diversi moduli attraverso interfacce ben documentate.

Le classi astratte sono aiutanti di coesione elevata da utilizzare durante l'implementazione di un'interfaccia, assumendo un certo livello di dettagli di implementazione. In alternativa, le classi astratte vengono utilizzate per la definizione di SPI, interfacce fornitore di servizi.

La differenza tra un'API e una SPI è sottile, ma importante: per un'API, l'attenzione è rivolta a chi la usa e per una SPI l'attenzione è su chi la implementa .

L'aggiunta di metodi a un'API è semplice, tutti gli utenti esistenti dell'API verranno comunque compilati. L'aggiunta di metodi a una SPI è difficile, poiché ogni fornitore di servizi (implementazione concreta) dovrà implementare i nuovi metodi. Se le interfacce vengono utilizzate per definire un SPI, un provider dovrà rilasciare una nuova versione ogni volta che il contratto SPI cambia. Se si utilizzano invece classi astratte, è possibile definire nuovi metodi in termini di metodi astratti esistenti o come throw not implemented exceptionstub vuoti , che consentiranno almeno una versione precedente di un'implementazione del servizio da compilare ed eseguire.

Una nota su Java 8 e metodi predefiniti

Sebbene Java 8 abbia introdotto metodi predefiniti per le interfacce, il che rende la linea tra le interfacce e le classi astratte ancora più sfocate, ciò non è stato così che le implementazioni possono riutilizzare il codice, ma per rendere più semplice cambiare le interfacce che servono sia come API che come SPI (o vengono erroneamente utilizzati per la definizione di SPI anziché per le classi astratte).

Quale usare?

  1. La cosa dovrebbe essere usata pubblicamente da altre parti del codice o da altro codice esterno? Aggiungi un'interfaccia ad esso per nascondere i dettagli di implementazione dal contratto astratto pubblico, che è il comportamento generale della cosa.
  2. È la cosa qualcosa che dovrebbe avere più implementazioni con un sacco di codice in comune? Realizza un'interfaccia e un'implementazione astratta e incompleta.
  3. Ci sarà mai una sola implementazione e nessun altro la utilizzerà? Basta renderlo una classe concreta.
    1. "ever" è molto tempo, puoi giocarci in sicurezza e aggiungere comunque un'interfaccia.

Un corollario: il contrario è spesso fatto erroneamente: quando usi una cosa , cerca sempre di usare la classe / interfaccia più generica di cui hai effettivamente bisogno. In altre parole, non dichiarare le variabili come ArrayList theList = new ArrayList(), a meno che tu non abbia effettivamente una dipendenza molto forte dal fatto che sia un elenco di array e nessun altro tipo di elenco lo taglierebbe per te. Usa List theList = new ArrayListinvece, o anche Collection theCollection = new ArrayListse il fatto che sia un elenco, e non qualsiasi altro tipo di raccolta non ha importanza.


4

Non proprio la risposta alla domanda originale, ma una volta che hai la risposta alla differenza tra loro, entrerai nel dilemma di quando usare ogni volta: quando usare interfacce o classi astratte? Quando usare entrambi?

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


3

L'ereditarietà viene utilizzata per due scopi:

  • Consentire a un oggetto di considerare i membri dei dati di tipo genitore e le implementazioni del metodo come propri.

  • Consentire a un riferimento a un oggetto di un tipo di essere utilizzato dal codice che prevede un riferimento all'oggetto supertipo.

Nei linguaggi / framework che supportano l'ereditarietà multipla generalizzata, spesso non è necessario classificare un tipo come "interfaccia" o "classe astratta". I linguaggi e le strutture popolari, tuttavia, consentiranno a un tipo di considerare propri i membri dei dati di un altro tipo o le implementazioni del metodo, anche se consentono a un tipo di essere sostituibile con un numero arbitrario di altri tipi.

Le classi astratte possono avere membri di dati e implementazioni di metodi, ma possono essere ereditate solo da classi che non ereditano da altre classi. Le interfacce non pongono quasi restrizioni sui tipi che le implementano, ma non possono includere membri di dati o implementazioni di metodi.

Ci sono momenti in cui è utile che i tipi siano sostituibili a molte cose diverse; ci sono altre volte in cui è utile che gli oggetti considerino propri i membri di dati di tipo genitore e le implementazioni dei metodi. Fare una distinzione tra interfacce e classi astratte consente a ciascuna di queste abilità di essere utilizzata nei casi in cui è più rilevante.


3

Punti chiave:

  • La classe astratta può avere entrambi proprietà, campi dati, metodi (completi / incompleti).
  • Se il metodo o le proprietà definiscono una parola chiave astratta che deve sovrascrivere nella classe derivata (funziona come una funzionalità strettamente accoppiata)
  • Se si definisce la parola chiave astratta per metodo o proprietà nella classe astratta, non è possibile definire il corpo del metodo e ottenere / impostare il valore per le proprietà e che deve sostituire la classe derivata.
  • La classe astratta non supporta l'ereditarietà multipla.
  • La classe astratta contiene costruttori.
  • Una classe astratta può contenere modificatori di accesso per sottotitoli, funzioni, proprietà.
  • Solo un membro completo della classe astratta può essere statico.
  • Un'interfaccia può ereditare solo da un'altra interfaccia e non può ereditare da una classe astratta, dove una classe astratta può ereditare da un'altra classe astratta o un'altra interfaccia.

Vantaggio:

  • È un tipo di contratto che obbliga tutte le sottoclassi a portare avanti le stesse gerarchie o standard.
  • Se varie implementazioni sono dello stesso tipo e usano un comportamento o uno stato comuni, è meglio usare la classe astratta.
  • Se aggiungiamo un nuovo metodo a una classe astratta, allora abbiamo la possibilità di fornire un'implementazione predefinita e quindi tutto il codice esistente potrebbe funzionare correttamente.
  • Permette un'esecuzione veloce dell'interfaccia (l'interfaccia richiede più tempo per trovare il metodo effettivo nelle classi corrispondenti).
  • Può essere utilizzato per un accoppiamento stretto e lento.

trova i dettagli qui ... http://pradeepatkari.wordpress.com/2014/11/20/interface-and-abstract-class-in-c-oops/


3

Il modo più breve per riassumere è che an interfaceè:

  1. Completamente astratto, a parte defaulte staticmetodi; mentre ha definizioni (firme di metodo + implementazioni) per defaulte staticmetodi, ha solo dichiarazioni (firme di metodo) per altri metodi.
  2. Fatte salve le regole più lassiste rispetto alle classi (una classe può implementare più interfaces e interfacepuò ereditare da più interfaces). Tutte le variabili sono implicitamente costanti, specificate come public static finalo meno. Tutti i membri sono implicitamente public, se specificati come tali o meno.
  3. Generalmente utilizzato come garanzia che la classe di implementazione avrà le caratteristiche specificate e / o sia compatibile con qualsiasi altra classe che implementa la stessa interfaccia.

Nel frattempo, una abstractclasse è:

  1. Ovunque da completamente astratto a completamente implementato, con la tendenza ad avere uno o più abstractmetodi. Può contenere sia dichiarazioni che definizioni, con le dichiarazioni contrassegnate come abstract.
  2. Una classe a tutti gli effetti, e soggetta alle regole che governano altre classi (può ereditare solo da una classe), a condizione che non possa essere istanziata (perché non c'è garanzia che sia pienamente implementata). Può avere variabili membro non costanti. In grado di implementare il controllo di accesso utente, limitando i membri come protected, private, o un pacchetto privato (non specificato).
  3. Generalmente utilizzato sia per fornire la maggior parte dell'implementazione che può essere condivisa da più sottoclassi, sia per fornire la maggior parte dell'implementazione che il programmatore è in grado di fornire.

Oppure, se vogliamo far bollire il tutto a una sola frase: An interfaceè quello che la classe che implementa ha , ma di una abstractclasse è quello che la sottoclasse è .


3

Vorrei aggiungere un'altra differenza che ha senso. Ad esempio, hai un framework con migliaia di righe di codice. Ora, se si desidera aggiungere una nuova funzionalità in tutto il codice usando un metodo enhanUI (), è meglio aggiungere quel metodo in classe astratta piuttosto che in interfaccia. Perché, se aggiungi questo metodo in un'interfaccia, dovresti implementarlo in tutta la classe implementata, ma non è il caso se aggiungi il metodo in classe astratta.


3

Per dare una risposta semplice ma chiara, aiuta a impostare il contesto: usi entrambi quando non vuoi fornire implementazioni complete.

La differenza principale quindi è che un'interfaccia non ha alcuna implementazione (solo metodi senza corpo) mentre le classi astratte possono avere membri e metodi con un corpo, cioè possono essere parzialmente implementate.


Poiché hai appena risposto, la tua risposta non tiene conto della defaultparola chiave in Java 8 con la quale puoi definire metodi concreti anche nelle interfacce.
Philantrovert,

Come ho detto, questa doveva essere una "risposta semplice ma chiara" per qualcuno nella fase di apprendimento, qual è la differenza. Per qualcuno del genere, non è di alcun vantaggio conoscere questo tipo di eccezione, sarebbe solo molto confuso.
user3775501,

3

Differenze tra classe astratta e interfaccia per conto della reale implementazione.

Interfaccia : è una parola chiave e viene utilizzata per definire il modello o la stampa blu di un oggetto e forza tutte le sottoclassi che seguiranno lo stesso prototipo, così come per l'implementazione, tutte le sottoclassi sono libere di implementare la funzionalità secondo è requisito.

Alcuni altri casi d'uso in cui dovremmo usare l'interfaccia.

Comunicazione tra due oggetti esterni (integrazione di terze parti nella nostra applicazione) tramite l' interfaccia qui L'interfaccia funziona come contratto.

Classe astratta: astratta, è una parola chiave e quando usiamo questa parola chiave prima di qualsiasi classe, questa diventa una classe astratta. Viene utilizzata principalmente quando è necessario definire il modello e alcune funzionalità predefinite di un oggetto seguite da tutti i sottoclassi e in questo modo rimuove il codice ridondante e un altro caso d'uso in cui possiamo usare la classe astratta , come se non volessimo che altre classi possano istanziare direttamente un oggetto della classe, solo le classi derivate possono usare la funzionalità.

Esempio di classe astratta:

 public abstract class DesireCar
  {

 //It is an abstract method that defines the prototype.
     public abstract void Color();

  // It is a default implementation of a Wheel method as all the desire cars have the same no. of wheels.   
 // and hence no need to define this in all the sub classes in this way it saves the code duplicasy     

  public void Wheel() {          

               Console.WriteLine("Car has four wheel");
                }
           }


    **Here is the sub classes:**

     public class DesireCar1 : DesireCar
        {
            public override void Color()
            {
                Console.WriteLine("This is a red color Desire car");
            }
        }

        public class DesireCar2 : DesireCar
        {
            public override void Color()
            {
                Console.WriteLine("This is a red white Desire car");
            }
        }

Esempio di interfaccia:

  public interface IShape
        {
          // Defines the prototype(template) 
            void Draw();
        }


  // All the sub classes follow the same template but implementation can be different.

    public class Circle : IShape
    {
        public void Draw()
        {
            Console.WriteLine("This is a Circle");
        }
    }

    public class Rectangle : IShape
    {
        public void Draw()
        {
            Console.WriteLine("This is a Rectangle");
        }
    }

3

Puoi trovare una chiara differenza tra interfaccia e classe astratta.

Interfaccia

  • L'interfaccia contiene solo metodi astratti.
  • Forzare gli utenti a implementare tutti i metodi quando implementa l'interfaccia.
  • Contiene solo variabili finali e statiche.
  • Dichiarare utilizzando la parola chiave dell'interfaccia.
  • Tutti i metodi di un'interfaccia devono essere definiti come pubblici.
  • Un'interfaccia può estendersi o una classe può implementare più altre interfacce.

Classe astratta

  • La classe astratta contiene metodi astratti e non astratti.

  • Non impone agli utenti di implementare tutti i metodi quando eredita la classe astratta.

  • Contiene tutti i tipi di variabili tra cui primitive e non primitive

  • Dichiarare utilizzando la parola chiave astratta.

  • Metodi e membri di una classe astratta possono essere definiti con qualsiasi visibilità.

  • Una classe figlio può estendere una sola classe (astratta o concreta).


2

Una classe astratta è una classe il cui oggetto non può essere creato o una classe che non può essere istanziata. Un metodo astratto rende un estratto di classe. Una classe astratta deve essere ereditata per sovrascrivere i metodi dichiarati nella classe astratta. Nessuna restrizione per gli specificatori di accesso. Una classe astratta può contenere metodi di costruzione e altri metodi concreti (metodi non abstarct) ma l'interfaccia non può avere.

Un'interfaccia è un modello / modello di metodi (ad es. Viene data una casa su un foglio (interfaccia) e diversi architetti useranno le loro idee per costruirla (le classi di architetti che implementano l'interfaccia della casa). È una raccolta di metodi astratti, metodi predefiniti, metodi statici, variabili finali e classi nidificate. Tutti i membri saranno finalisti o pubblici, non sono consentiti specificatori di accesso protetti e privati. Non è consentita la creazione di oggetti. Per utilizzare il implementando l'interfaccia e anche per sovrascrivere il metodo astratto dichiarato nell'interfaccia. Un'interfaccia è un buon esempio di accoppiamento libero (polimorfismo dinamico / legame dinamico) Un'interfaccia implementa il polimorfismo e l'astrazione. Dice cosa fare ma come fare è definito dal classe di esecuzione. Ad esempio. "è una casa automobilistica e vuole che alcune caratteristiche siano le stesse per tutta la macchina che sta producendo, così che la compagnia produrrebbe un veicolo di interfaccia che avrà quelle caratteristiche e diverse classi di auto (come Maruti Suzkhi, Maruti 800) avranno la precedenza quelle caratteristiche (funzioni).

Perché interfacciarsi quando abbiamo già una classe astratta? Java supporta solo l'ereditarietà multilivello e gerarchica ma con l'aiuto dell'interfaccia possiamo implementare l'ereditarietà multipla.


2

In termini di praticità (JAVA), la principale differenza tra la classe astratta e l'interfaccia è che la classe astratta può contenere lo stato. Oltre allo stato di mantenimento, possiamo anche eseguire operazioni di riposo con Interface.


1

In un'interfaccia tutti i metodi devono essere solo definizioni, non uno singolo dovrebbe essere implementato.

Ma in una classe astratta ci deve essere un metodo astratto con una sola definizione, ma altri metodi possono essere anche nella classe astratta con l'implementazione ...


1

Abbiamo varie differenze strutturali / sintattiche tra interfaccia e classe astratta. Altre differenze sono

[1] Differenza basata sullo scenario :

Le classi astratte vengono utilizzate negli scenari in cui si desidera limitare l'utente alla creazione di oggetti di classe superiore E riteniamo che in futuro verranno aggiunti altri metodi astratti.

L'interfaccia deve essere utilizzata quando siamo sicuri che non ci può essere più alcun metodo astratto da fornire. Quindi viene pubblicata solo un'interfaccia.

[2] Differenza concettuale :

"Dobbiamo fornire metodi più astratti in futuro" se SÌ lo rendono di classe astratta e se NO lo rende Interfaccia.

(Più appropriato e valido fino a java 1.7)


1

di solito classe astratta usata per il nucleo di qualcosa ma interfaccia usata per aggiungere periferiche.

quando si desidera creare un tipo di base per il veicolo, è necessario utilizzare la classe astratta, ma se si desidera aggiungere alcune funzionalità o proprietà che non fanno parte del concetto di base del veicolo, è necessario utilizzare l'interfaccia, ad esempio si desidera aggiungere la funzione "ToJSON ()" .

l'interfaccia ha una vasta gamma di astrazioni piuttosto che di classe astratta. puoi vederlo passando argomenti. Guarda questo esempio:

inserisci qui la descrizione dell'immagine

se usi il veicolo come argomento, puoi semplicemente usare uno del suo tipo derivato (bus o auto-stessa categoria-solo categoria del veicolo). ma quando usi l'interfaccia IMoveable come argomento hai più possibilità di scelta.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.