Interface vs Abstract Class (OO generale)


1413

Di recente ho avuto due interviste telefoniche in cui mi è stato chiesto delle differenze tra un'interfaccia e una classe astratta. Ho spiegato ogni loro aspetto a cui potevo pensare, ma sembra che stiano aspettando che menzionassi qualcosa di specifico, e non so di cosa si tratti.

Dalla mia esperienza penso che quanto segue sia vero. Se mi manca un punto importante, per favore fatemelo sapere.

Interfaccia:

Ogni singolo metodo dichiarato in un'interfaccia dovrà essere implementato nella sottoclasse. In un'interfaccia possono esistere solo eventi, delegati, proprietà (C #) e metodi. Una classe può implementare più interfacce.

Classe astratta:

Solo i metodi astratti devono essere implementati dalla sottoclasse. Una classe astratta può avere metodi normali con implementazioni. La classe astratta può anche avere variabili di classe accanto a Eventi, Delegati, Proprietà e Metodi. Una classe può implementare solo una classe astratta solo a causa della non esistenza di ereditarietà multipla in C #.

  1. Dopo tutto ciò, l'intervistatore ha posto la domanda "E se avessi una lezione astratta con solo metodi astratti? In che modo sarebbe diverso da un'interfaccia?" Non sapevo la risposta, ma penso che sia l'eredità come menzionato sopra giusto?

  2. Un altro intervistatore mi ha chiesto cosa sarebbe successo se avessi una variabile pubblica all'interno dell'interfaccia, come sarebbe diverso rispetto alla classe astratta? Ho insistito sul fatto che non puoi avere una variabile pubblica all'interno di un'interfaccia. Non sapevo cosa voleva sentire, ma non era neppure soddisfatto.

Vedi anche :


412
Mentre penso che sia importante conoscere la differenza tra i due, questa non è una buona domanda per l'intervista, imo. A meno che il lavoro non stia scrivendo un libro su argomenti OO. Farai meglio a non lavorare per quei pipistrelli.
Alan,

107
@Alan: In realtà mi piace come una domanda di intervista, ma non perseguiterei qualcuno in questo modo - probabilmente lo pubblicherei più come "Dove sceglieresti un'interfaccia su una classe base astratta, quando definisci una gerarchia? "o qualcosa di simile.
Reed Copsey,

11
Forse cercavano una risposta più incentrata sul design ... anche se come te l'avrei trattata come una domanda tecnica.
CurtainDog

16
Belle differenze tabulari qui: mindprod.com/jgloss/interfacevsabstract.html
Rajat_R

30
@Kave: I insisted you can't have a public variable inside an interface.penso che l'interfaccia possa avere una variabile pubblica. Infatti le variabili nell'interfaccia sono automaticamente pubbliche e definitive.
uno studente il

Risposte:


746

Mentre la tua domanda indica che è per "OO generale", sembra davvero concentrarsi sull'uso di .NET di questi termini.

In .NET (simile a Java):

  • le interfacce non possono avere stato o implementazione
  • una classe che implementa un'interfaccia deve fornire un'implementazione di tutti i metodi di tale interfaccia
  • le classi astratte possono contenere stato (membri dei dati) e / o implementazione (metodi)
  • le classi astratte possono essere ereditate senza implementare i metodi astratti (sebbene tale classe derivata sia essa stessa astratta)
  • le interfacce possono essere ereditate in modo multiplo, le classi astratte potrebbero non esserlo (questa è probabilmente la ragione concreta chiave per l'esistenza di interfacce separatamente dalle classi abtract - consentono un'implementazione dell'ereditarietà multipla che elimina molti dei problemi dell'MI generale).

Come termini generali di OO, le differenze non sono necessariamente ben definite. Ad esempio, ci sono programmatori C ++ che possono contenere definizioni rigide simili (le interfacce sono un sottoinsieme rigoroso di classi astratte che non possono contenere l'implementazione), mentre alcuni potrebbero dire che una classe astratta con alcune implementazioni predefinite è ancora un'interfaccia o che un non astratto la classe può ancora definire un'interfaccia.

In effetti, esiste un linguaggio C ++ chiamato Non-Virtual Interface (NVI) in cui i metodi pubblici sono metodi non virtuali che "thunk" a metodi virtuali privati:


7
Grazie. Penso che poiché la tua risposta menziona lo stato + una buona panoramica di tutto il resto, segnalo la tua risposta come risposta finale. Hai ragione, ho chiesto OO generale, dal momento che il mio primo intervistatore ha chiesto OO generale, ma poiché sono un ragazzo C #, tendo a dimenticarlo. ;-) Grazie anche per la spiegazione del C ++, come sempre il c ++ è strabiliante.
Houman,

6
Penso che un punto chiave nella spiegazione fornita da Michael sia che quando si implementa un'interfaccia DEVI implementare tutti i membri nell'interfaccia, ma quando erediti da una classe astratta NON È NECESSARIO da una classe figlio per implementare i membri dei suoi genitori
Guillermo Gomez

82
+1: sarei disposto a scommettere che quelle scimmie che ospitano l'intervista non si rendono nemmeno conto che altre lingue implementano OO in modo diverso.
Razze di leggerezza in orbita l'

2
@JL Non vedo dove sia il problema. Sembra che tu abbia confuso il metodo astratto con la classe astratta. I metodi astratti non hanno implementazione. Tuttavia, all'interno di una classe astratta , alcuni metodi possono essere astratti (cioè senza implementazione) mentre altri possono effettivamente avere implementazione.
xji,

19
Si noti che in Java 8 ora è possibile avere metodi predefiniti e metodi statici nelle interfacce, il che significa che le interfacce Java possono avere un'implementazione. Riferimento qui . Ovviamente ti riferivi principalmente a .NET, quindi questa è solo un'osservazione che si riferisce a Java.
David

867

Che ne dici di un'analogia: quando ero nell'Aeronautica, sono andato all'addestramento dei piloti e sono diventato un pilota USAF (US Air Force). A quel punto non ero qualificato per volare nulla e dovevo frequentare l'addestramento per tipo di aereo. Una volta che mi sono qualificato, ero un pilota (classe astratta) e un pilota C-141 (classe concreta). In uno dei miei incarichi, mi è stato assegnato un compito aggiuntivo: responsabile della sicurezza. Ora ero ancora un pilota e un pilota C-141, ma ho anche svolto compiti di responsabile della sicurezza (ho implementato ISafetyOfficer, per così dire). A un pilota non era richiesto di essere un ufficiale di sicurezza, anche altre persone avrebbero potuto farlo.

Tutti i piloti USAF devono attenersi a determinati regolamenti dell'Aeronautica e tutti i piloti C-141 (o F-16 o T-38) "sono" piloti USAF. Chiunque può essere un ufficiale di sicurezza. Quindi, per riassumere:

  • Pilota: classe astratta
  • C-141 Pilota: classe concreta
  • Responsabile ISafety: interfaccia

nota aggiunta: questa doveva essere un'analogia per aiutare a spiegare il concetto, non una raccomandazione di codifica. Vedi i vari commenti qui sotto, la discussione è interessante.


87
Mi piace molto questa analogia, usa un semplice esempio per spiegare un argomento leggermente complesso
Kevin Bowersox,

13
Questo è il modo migliore per comprendere la terminologia OO complessa. In breve, tutta la teoria vale solo quando puoi usarla praticamente. @Jay rexample è davvero facile da afferrare quindi diversi punti elenco (per lo più penetranti nella mente invece di essere assorbiti!)
vs

54
Sono ancora un po 'confuso. Ad esempio, ora hai ottenuto le qualifiche F-16 e T-38, quindi ora la classe Jaynon può ereditare da più classi (pilota C-141, pilota F-16 e pilota T-38), significa che le cui classi dovrebbero diventare interfacce? Grazie
Alex Okrushko il

37
Molte persone hanno giustamente dato un +1 al commento di Alex, poiché rivela un po 'di debolezza in questo esempio. Innanzitutto, direi che Jay sarebbe un'istanza di C-141Pilot piuttosto che la sua stessa classe. Inoltre, poiché negli USAF il 99% di tutti i piloti sono qualificati su un solo velivolo alla volta (FCF e i piloti di test sono eccezioni notevoli), non ho preso in considerazione più qualifiche e le modalità per implementarle. Come so di un pilota che, 50 anni fa, era qualificato su 25 diversi aeromobili contemporaneamente, penso che esemplifichi il modo in cui NON vogliamo usare l'ereditarietà multipla.
Jay,

20
Dato che è improbabile che un pilota voli più di un aereo alla volta, sarebbe una buona opportunità per attuare il modello strategico. Un pilota avrebbe una collezione di certificazioni e selezionerà quella corretta in fase di esecuzione. Le certificazioni verrebbero codificate come comportamenti che implementerebbero l'interfaccia IFlyPlane, con i metodi TakeOff, Land, Eject.
Michael Blackburn,

221

Penso che la risposta che stanno cercando sia la differenza filosofica fondamentale o OPPS.

L'ereditarietà della classe astratta viene utilizzata quando la classe derivata condivide le proprietà e il comportamento principali della classe astratta. Il tipo di comportamento che definisce effettivamente la classe.

D'altra parte, l'ereditarietà dell'interfaccia viene utilizzata quando le classi condividono il comportamento periferico, quelle che non definiscono necessariamente la classe derivata.

Per es. Un'auto e un camion condividono molte proprietà e comportamenti fondamentali di una classe astratta di Automobile, ma condividono anche alcuni comportamenti periferici come Genera scarico che condividono anche classi non automobilistiche come Drillers o PowerGenerators e non definisce necessariamente un'auto o un camion , quindi Car, Truck, Driller e PowerGenerator possono condividere la stessa interfaccia IExhaust.


32
Penso che un'analogia ancora migliore sarebbe "usiFuel" che mostrerebbe la natura contrattuale dell'interfaccia.
Pureferret,

@Pureferret se acceleratefa parte del comportamento fondamentale della classe astratta Automobile, quindi non posso dire che acceleratemostri la natura del contratto . qual è la natura del contratto? perché questa parola è stata contractintrodotta ogni volta che ne parliamo interface?
Scambio eccessivo

@overexchange perché in genere l'interfaccia è proprio dove due 'superfici' si incontrano, ma la parola contratto implica che c'è un accordo su come si incontrano le due 'superfici'. Non ha senso (almeno per me) che generare gas di scarico sia qualcosa su cui "sei d'accordo". Ma ha senso (ancora una volta per me) che tu possa essere d'accordo sulla necessità di usare Fuel.
Pureferret,

1
@Pureferret ho sollevato una query al link per lo stesso
scambio eccessivo

1
@Pureferret se interfacedeve avere un comportamento periferico, allora perché public interface List<E> extends Collection<E> {}è progettato per descrivere il comportamento centrale di list? questo in realtà contraddice la risposta di Prasun. Entrambi Collection<E>e List<E>sono interfacce qui.
Scambio eccessivo del

198

Breve: le classi astratte sono usate per modellare una gerarchia di classi di classi simili (ad esempio Animale può essere una classe astratta e Umano, Leone, Tigre possono essere classi derivate concrete)

E

L'interfaccia viene utilizzata per la comunicazione tra 2 classi simili / non simili a cui non interessa il tipo di classe che implementa l'interfaccia (ad esempio Height può essere proprietà dell'interfaccia e può essere implementata da Human, Building, Tree. Non importa se si può mangiare , puoi nuotare, puoi morire o altro .. importa solo una cosa che devi avere Altezza (implementazione nella tua classe)).


7
Mi piace molto questa risposta perché a volte è difficile rispondere al "che cosa" è diverso tra le cose guardando qualcosa di più astratto come l' intento , anziché solo la struttura (come strutturalmente, un'interfaccia e una classe astratta pura sono praticamente le stesse cosa).
LostSalad,

È facile enumerare ciò che una classe astratta rispetto a un'interfaccia può fare in un linguaggio specifico, ma è più difficile creare un'astrazione per dare significato e responsabilità all'oggetto e ciò che hai detto riprende totalmente l'uso del concetto 2 in OO. Grazie!
Samuel,

2
@dhananjay: vedo come l'altezza può essere separata dal concetto di classe Animale e può appartenere a un'altra classe diversa, ma cosa intendi esattamente per "comunicazione" tra le classi? Sta semplicemente definendo Height per la sua stessa classe, giusto?
TTT,

77

Ci sono un paio di altre differenze -

Le interfacce non possono avere implementazioni concrete. Le classi di base astratte possono. Ciò ti consente di fornire implementazioni concrete lì. Ciò può consentire a una classe base astratta di fornire effettivamente un contratto più rigoroso, laddove un'interfaccia descrive in realtà solo il modo in cui viene utilizzata una classe. (La classe base astratta può avere membri non virtuali che definiscono il comportamento, il che conferisce maggiore controllo all'autore della classe base.)

È possibile implementare più di un'interfaccia su una classe. Una classe può derivare solo da una singola classe base astratta. Ciò consente la gerarchia polimorfica utilizzando le interfacce, ma non le classi base astratte. Ciò consente anche una pseudo-ereditarietà multipla mediante interfacce.

Le classi di base astratte possono essere modificate in v2 + senza interrompere l'API. Le modifiche alle interfacce stanno rompendo le modifiche.

[C # /. NET Specific] Le interfacce, a differenza delle classi di base astratte, possono essere applicate ai tipi di valore (strutture). Le strutture non possono ereditare da classi base astratte. Ciò consente di applicare contratti comportamentali / linee guida di utilizzo sui tipi di valore.


5
+1 per il punto chiave che più di un'interfaccia può essere implementata su una classe.
CG

Questo è l'unico vero vantaggio delle interfacce rispetto alle classi base astratte, IMO. Altrimenti, sono d'accordo con le linee guida di progettazione .NET, che ora affermano di "preferire le classi di base astratte rispetto alle interfacce"
Reed Copsey,

Tuttavia, sarebbe utile se si potesse aggiungere il punto che le sue interfacce possono essere applicate a qualsiasi classe.
CG

1
@altCognito: ho pensato che fosse gestito in qualche modo con il secondo paragrafo. Questo mi ha ricordato, tuttavia, che le interfacce funzionano su tipi di valore, quindi l'ho aggiunto.
Reed Copsey,

Grazie mille per questa descrizione esatta. È davvero molto utile. Sono nuovo qui. È un peccato non poter selezionare due risposte come "risposta". Una cosa che mi confonde è il tuo uso della classe "base" astratta. Tutte le classi astratte sono pensate per essere una classe base di una sottoclasse. Perché nominare l'extra 'base'?
Houman,

68

Ereditarietà
Considera un'auto e un autobus. Sono due veicoli diversi. Tuttavia, condividono alcune proprietà comuni come hanno uno sterzo, freni, ingranaggi, motore ecc.
Quindi, con il concetto di eredità, questo può essere rappresentato come segue ...

public class Vehicle {
    private Driver driver;
    private Seat[] seatArray; //In java and most of the Object Oriented Programming(OOP) languages, square brackets are used to denote arrays(Collections).
    //You can define as many properties as you want here ...
}

Adesso una bicicletta ...

public class Bicycle extends Vehicle {
    //You define properties which are unique to bicycles here ...
    private Pedal pedal;
}

E una macchina ...

public class Car extends Vehicle {
    private Engine engine;
    private Door[] doors;
}

Questo è tutto sull'eredità . Li usiamo per classificare gli oggetti in forme Base più semplici e i loro figli, come abbiamo visto sopra.

Classi astratte

Le classi astratte sono oggetti incompleti . Per capirlo ulteriormente, consideriamo ancora una volta l'analogia del veicolo.
Un veicolo può essere guidato. Giusto? Ma veicoli diversi sono guidati in modi diversi ... Ad esempio, non puoi guidare un'auto proprio mentre guidi una bicicletta.
Quindi, come rappresentare la funzione di guida di un veicolo? È più difficile controllare che tipo di veicolo sia e guidarlo con la propria funzione; dovresti cambiare ancora e ancora la classe del conducente quando aggiungi un nuovo tipo di veicolo.
Ecco che arriva il ruolo di classi e metodi astratti. È possibile definire il metodo di azionamento come astratto per indicare che ogni figlio ereditario deve implementare questa funzione.
Quindi se modifichi la classe del veicolo ...

//......Code of Vehicle Class
abstract public void drive();
//.....Code continues

La bicicletta e l'auto devono anche specificare come guidarla. In caso contrario, il codice non verrà compilato e verrà generato un errore.
In breve ... una classe astratta è una classe parzialmente incompleta con alcune funzioni incomplete, che i figli ereditari devono specificare la propria.

Interfacce Le interfacce sono totalmente incomplete. Non hanno proprietà. Indicano solo che i figli ereditari sono in grado di fare qualcosa ...
Supponi di avere diversi tipi di telefoni cellulari con te. Ognuno di essi ha modi diversi di svolgere funzioni diverse; Es: chiama una persona. Il produttore del telefono specifica come farlo. Qui i telefoni cellulari possono comporre un numero, ovvero è in grado di comporre il numero. Rappresentiamo questo come un'interfaccia.

public interface Dialable {
    public void dial(Number n);
}

Qui il creatore del Dialable definisce come comporre un numero. Devi solo dargli un numero da comporre.

// Makers define how exactly dialable work inside.

Dialable PHONE1 = new Dialable() {
    public void dial(Number n) {
        //Do the phone1's own way to dial a number
    }
}

Dialable PHONE2 = new Dialable() {
    public void dial(Number n) {
        //Do the phone2's own way to dial a number
    }
}


//Suppose there is a function written by someone else, which expects a Dialable
......
public static void main(String[] args) {
    Dialable myDialable = SomeLibrary.PHONE1;
    SomeOtherLibrary.doSomethingUsingADialable(myDialable);
}
.....

Con la presente utilizzando le interfacce anziché le classi astratte, lo scrittore della funzione che utilizza un Dialable non deve preoccuparsi delle sue proprietà. Es: ha un touch-screen o una tastiera, è un telefono fisso o cellulare? Hai solo bisogno di sapere se è discutibile; eredita (o implementa) l'interfaccia Dialable.

E , soprattutto , se un giorno cambierai il Dialable con un altro

......
public static void main(String[] args) {
    Dialable myDialable = SomeLibrary.PHONE2; // <-- changed from PHONE1 to PHONE2
    SomeOtherLibrary.doSomethingUsingADialable(myDialable);
}
.....

Puoi essere sicuro che il codice funzioni ancora perfettamente perché la funzione che utilizza il dialable non dipende (e non può) dipendere da dettagli diversi da quelli specificati nell'interfaccia Dialable. Entrambi implementano un'interfaccia Dialable ed è l'unica cosa a cui interessa la funzione.

Le interfacce sono comunemente utilizzate dagli sviluppatori per garantire l'interoperabilità (utilizzare in modo intercambiabile) tra oggetti, nella misura in cui condividono una funzione comune (proprio come è possibile passare a un telefono fisso o cellulare, nella misura in cui è sufficiente comporre un numero). In breve, le interfacce sono una versione molto più semplice delle classi astratte, senza proprietà.
Inoltre, tieni presente che puoi implementare (ereditare) tutte le interfacce che desideri, ma puoi estendere (ereditare) una sola classe genitore.

Altre informazioni Classi astratte vs interfacce


Non è vero che "Le interfacce non hanno proprietà".
Bigeyes,

@Bigeyes, java non consente proprietà nelle interfacce. Ho pensato che fosse lo stesso anche in altre lingue. Potresti spiegare di più?
fz_salam,

Mi riferisco a C # /. Net. Vedi l' esempio
Bigeyes,

@Bigeyes per C # dove le interfacce possono avere proprietà, non reintroduce il problema dell'ereditarietà multipla? Cosa succede quando una classe utilizza più interfacce che hanno definito la stessa proprietà? Solo curiosi grazie
stackPusher il

@happycoder: re: "Qui usando le interfacce anziché le classi astratte, non devi preoccuparti delle sue proprietà. Es: ha un touch-screen o una tastiera, è un telefono fisso o cellulare fisso. Devi solo sapere se è dialable; eredita (o implementa) l'interfaccia Dialable. " - puoi mostrarlo in un esempio di codice, inoltre non ho visto come sarebbe ereditato ...
TTT,

45

Se consideri javail linguaggio OOP come risposta a questa domanda, la versione Java 8 rende obsoleto parte del contenuto delle risposte precedenti. Ora l'interfaccia java può avere metodi predefiniti con un'implementazione concreta.

Il sito Web Oracle offre differenze chiave tra interfacee abstractclasse.

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.

In termini semplici, vorrei usare

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

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

Dai un'occhiata all'esempio di codice per capire le cose in modo chiaro: come avrei dovuto spiegare la differenza tra un'interfaccia e una classe astratta?


33

Gli intervistatori stanno abbaiando su uno strano albero. Per linguaggi come C # e Java, c'è una differenza, ma in altri linguaggi come C ++ non esiste. La teoria OO non differenzia i due, semplicemente la sintassi del linguaggio.

Una classe astratta è una classe con sia l'implementazione che l'interfaccia (metodi virtuali puri) che verranno ereditati. Le interfacce generalmente non hanno alcuna implementazione ma solo funzioni virtuali pure.

In C # o Java una classe astratta senza alcuna implementazione differisce da un'interfaccia solo nella sintassi utilizzata per ereditare da essa e dal fatto che puoi ereditare solo da una.


Mi è stata posta la stessa domanda una settimana fa, non ho esperienza con Java ma lavoro con C ++ da un po 'di tempo. L'intervistatore non ha specificato le lingue prima di porre la domanda, quindi ho solo spiegato che le interfacce in questo caso erano classi astratte senza stato o implementazioni di alcun tipo. Sono d'accordo che anche questa è una domanda strana.
dacabdi,

31

Con l'implementazione delle interfacce si ottengono composizione (relazioni "ha-a") anziché ereditarietà (relazioni "is-a"). Questo è un principio importante da ricordare quando si tratta di cose come i modelli di progettazione in cui è necessario utilizzare le interfacce per ottenere una composizione di comportamenti anziché un'eredità.


17
Le interfacce raggiungono, IMO, più una relazione "Atti-come-un". L'incapsulamento ottiene una composizione migliore di un'interfaccia.
Reed Copsey,

12
Non credo che l'implementazione delle interfacce verrebbe sotto composizione.
Pavan Dittakavi,

Inoltre, l'interfaccia è più probabile che utilizzi per descrivere "capacità", come IDisposable. Ha usato per condividere la funzionalità tra le classi che queste classi "sono in grado di fare" qualcosa. Altri esempi IFlyable può essere implementato per uccelli e aerei. Ma Bird può derivare da Creature di classe in cui i velivoli derivano da AirCraft.
Peter

26

spiegherò i dettagli di profondità dell'interfaccia e della classe astratta. Se conosci una panoramica dell'interfaccia e della classe astratta, allora ti viene in mente la prima domanda quando dovremmo usare l'interfaccia e quando dovremmo usare la classe astratta. Quindi, controlla di seguito la spiegazione dell'interfaccia e della classe astratta.

  1. Quando dovremmo usare l'interfaccia?

    se non conosci l'implementazione, abbiamo solo le specifiche dei requisiti, quindi andiamo con Interface

  2. Quando dovremmo usare la classe astratta?

    se conosci l'implementazione ma non completamente (in parte l'implementazione), andiamo con la classe Abstract.

    Interfaccia

    ogni metodo di default astratto pubblico significa che l'interfaccia è astratta al 100%.

    Astratto

    può avere il metodo Concrete e il metodo Abstract, che è il metodo Concrete, che ha un'implementazione nella classe Abstract, Una classe astratta è una classe dichiarata astratta, che può o meno includere metodi astratti.

    Interfaccia

    Non possiamo dichiarare l'interfaccia come privata, protetta

    D. Perché non dichiariamo Interface privata e protetta?

    Perché per impostazione predefinita il metodo di interfaccia è astratto pubblico così e quindi quella ragione per cui non dichiariamo l'interfaccia come privata e protetta.

    Il metodo di interfaccia
    , inoltre, non possiamo dichiarato interfaccia come privato, protetto, finale, statica, sincronizzato, nativo .....

    darò il motivo: perché non stiamo dichiarando il metodo sincronizzato perché non possiamo creare oggetto di interfaccia e sincronizzare stiamo lavorando sull'oggetto così e la ragione figlio che non stiamo dichiarando il metodo sincronizzato Anche il concetto di transitorio non è applicabile perché il lavoro transitorio con sincronizzato.

    Astratto

    siamo felici di usarlo con statico finale pubblico, privato .... significa che nessuna limitazione è applicabile in astratto.

    Interfaccia

    Le variabili sono dichiarate in Interface come un finale statico pubblico di default quindi non siamo dichiarate variabili come private, protette.

    Anche il modificatore volatile non è applicabile nell'interfaccia poiché la variabile di interfaccia è per impostazione predefinita variabile finale statica pubblica e finale che non è possibile modificare il valore una volta assegnato il valore in variabile e una volta dichiarata variabile in interfaccia è necessario assegnare la variabile.

    E la variabile volatile è continua sui cambiamenti, quindi è opp. alla fine questo è il motivo per cui non usiamo la variabile volatile nell'interfaccia.

    Astratto

    Variabile astratta non è necessario dichiarare finale statico pubblico.

spero che questo articolo sia utile.


4
Non sono d'accordo con questo punto: Abstract class must have at lease one abstract method.è possibile avere una classe Abstract senza un metodo Abstract, purché sia ​​implementata. RIFERIMENTO: An abstract class is a class that is declared abstract—it may or may not include abstract methods.FONTE DI RIFERIMENTO: docs.oracle.com/javase/tutorial/java/IandI/abstract.html
Devner

Stai parlando di dettagli tecnici e di implementazione, non stai rispondendo alla domanda in termini di OOP generale
Billal Begueradj,

26

Concettualmente parlando, mantenendo l'implementazione specifica della lingua, le regole, i benefici e il raggiungimento di qualsiasi obiettivo di programmazione usando chiunque o entrambi, può o non può avere codice / dati / proprietà, blah blah, eredità singole o multiple, tutto da parte

1- La classe Abstract (o pure abstract) intende implementare la gerarchia. Se i tuoi oggetti business sembrano strutturalmente simili, rappresentando solo un tipo di relazione genitore-figlio (gerarchia), verranno utilizzate le classi di ereditarietà / Abstract. Se il tuo modello di business non ha una gerarchia, l'ereditarietà non dovrebbe essere utilizzata (qui non sto parlando di logica di programmazione, ad esempio alcuni modelli di progettazione richiedono l'ereditarietà). Concettualmente, la classe astratta è un metodo per implementare la gerarchia di un modello di business in OOP, non ha nulla a che fare con le interfacce, in realtà confrontare la classe astratta con l'interfaccia non ha senso perché entrambe sono cose concettualmente totalmente diverse, nelle interviste viene chiesto solo di verificare i concetti, poiché sembra entrambi fornire la stessa funzionalità in termini di implementazione e noi programmatori di solito enfatizziamo maggiormente la codifica. [Tieni presente anche questo che l'astrazione è diversa dalla classe astratta].

2- un'interfaccia è un contratto, una funzionalità aziendale completa rappresentata da una o più serie di funzioni. Ecco perché è implementato e non ereditato. Un oggetto business (parte di una gerarchia o meno) può avere un numero qualsiasi di funzionalità aziendali complete. Non ha nulla a che fare con le classi astratte significa ereditarietà in generale. Ad esempio, un essere umano può ESEGUIRE, un elefante può ESEGUIRE, un uccello può ESEGUIRE, e così via, tutti questi oggetti di diversa gerarchia implementerebbero l'interfaccia ESEGUI o l'interfaccia EAT o SPEAK. Non entrare nell'implementazione in quanto potresti implementarla con classi astratte per ogni tipo che implementa queste interfacce. Un oggetto di qualsiasi gerarchia può avere una funzionalità (interfaccia) che non ha nulla a che fare con la sua gerarchia.

Credo che le interfacce non siano state inventate per ottenere eredità multiple o per esporre comportamenti pubblici e allo stesso modo, le classi astratte pure non devono sovrascrivere le interfacce ma l'interfaccia è una funzionalità che un oggetto può fare (tramite le funzioni di tale interfaccia) e la classe astratta rappresenta un genitore di una gerarchia per produrre figli con struttura principale (proprietà + funzionalità) del genitore

Quando ti viene chiesto della differenza, in realtà è la differenza concettuale non la differenza nell'implementazione specifica del linguaggio, a meno che non sia esplicitamente chiesto.

Credo che entrambi gli intervistatori si aspettassero una differenza netta tra questi due e quando hai fallito hanno provato a guidarti verso questa differenza implementando ONE come ALTRO

E se avessi una classe astratta con solo metodi astratti?


Questo riassume abbastanza bene la risposta a questa domanda.
pranavn,

funzionalità implementata vs struttura estesa, bello!
harshvchawla,

21

Per .Net,

La tua risposta a Il secondo intervistatore è anche la risposta al primo ... Le classi astratte possono avere implementazione e stato, le interfacce non possono ...

EDIT: In un'altra nota, non userei nemmeno la frase "sottoclasse" (o la frase "ereditarietà") per descrivere le classi che sono "definite per implementare" un'interfaccia. Per me, un'interfaccia è una definizione di un contratto a cui una classe deve conformarsi se è stata definita per "implementare" quell'interfaccia. Non eredita nulla ... Devi aggiungere tutto da solo, esplicitamente.


2
Sì! Stato! Ecco cosa intendeva il secondo intervistatore con il suo strano modo di dire "variabile pubblica" all'interno di un'interfaccia. Perbacco! Le classi astratte possono avere uno stato, le interfacce no! E sì, anche tutti gli altri concordano sulle differenze tra i loro modi di eredità, che avevo dimenticato di menzionare, ma ho capito già in seguito. :) Grazie a tutti!
Houman,

4
Più che semplicemente stato .... Le classi astratte possono avere ATTUAZIONE. vale a dire, possono avere metodi con codice che esegue e fa qualcosa, che viene ereditato ed eseguito da istanze delle classi base ... Non così con le interfacce
Charles Bretana

Inoltre, in un certo senso, le classi astratte POSSONO essere istanziate, devono solo essere istanziate usando una definizione di classe derivata, non direttamente. Ma le variabili di stato definite nella classe astratta vengono istanziate nell'oggetto creato da una nuova istanza della classe derivata. Questa istanza È un'istanza della classe astratta oltre ad essere un'istanza della classe derivata - dopo tutto è derivata da essa. Niente di tutto ciò è vero per un'interfaccia.
Charles Bretana,

Quando si reinstalla un'istanza di una classe definita per implementare un'interfaccia, non si tratta di una "istanza" di tale interfaccia, tutta la sintassi fa sì che il compilatore esamini il codice per la classe e si assicuri che ogni comportamento (metodo, proprietà , event, eventHandler, ecc.) definito dall'interfaccia è stato implementato nel codice per la classe.
Charles Bretana,

20

Interfaccia : deve essere utilizzata se si desidera implicare una regola sui componenti che possono essere o meno correlati tra loro

Professionisti:

  1. Consente l'ereditarietà multipla
  2. Fornisce astrazione non esponendo quale tipo esatto di oggetto viene utilizzato nel contesto
  3. fornisce coerenza con una firma specifica del contratto

Contro:

  1. Deve implementare tutti i contratti definiti
  2. Impossibile avere variabili o delegati
  3. Una volta definito non può essere modificato senza interrompere tutte le classi

Classe astratta : deve essere utilizzata dove si desidera avere un comportamento o un'implementazione di base o predefinita per componenti correlati tra loro

Professionisti:

  1. Più veloce dell'interfaccia
  2. Ha flessibilità nell'implementazione (puoi implementarla in tutto o in parte)
  3. Può essere facilmente modificato senza interrompere le classi derivate

Contro:

  1. Non può essere istanziato
  2. Non supporta l'ereditarietà multipla

Definisci più velocemente. È significativo? Che cosa significa? opcode per invocazione di funzioni su una classe astratta è più veloce di opcode per invocazione di funzioni su un'interfaccia?
denis631,

@ denis631 La classe astratta è leggermente più veloce dell'interfaccia a causa della ricerca e la chiamata è coinvolta nel metodo dell'interfaccia. leggi questo coderanch.com/t/503450/java/abstract-class-faster-interface
webmaster bourax

17

Penso che non gli sia piaciuta la tua risposta perché hai dato le differenze tecniche anziché quelle di progettazione. La domanda è come una domanda da troll per me. In effetti, le interfacce e le classi astratte hanno una natura completamente diversa, quindi non puoi davvero confrontarle. Ti darò la mia visione di qual è il ruolo di un'interfaccia e qual è il ruolo di una classe astratta.

interfaccia: viene utilizzato per garantire un contratto e creare un basso accoppiamento tra le classi al fine di avere un'applicazione più gestibile, scalabile e verificabile.

classe astratta: viene utilizzata solo per fattorizzare un codice tra classi della stessa responsabilità. Nota che questo è il motivo principale per cui l'ereditarietà multipla è una cosa negativa in OOP, perché una classe non dovrebbe gestire molte responsabilità (usa invece la composizione ).

Quindi le interfacce hanno un vero ruolo architettonico, mentre le classi astratte sono quasi solo un dettaglio dell'implementazione (se lo usi correttamente ovviamente).


13
After all that, the interviewer came up with the question "What if you had an 
Abstract class with only abstract methods? How would that be different
from an interface?" 

I documenti affermano chiaramente che se una classe astratta contiene solo dichiarazioni di metodi astratti, dovrebbe invece essere dichiarata come interfaccia.

An another interviewer asked me what if you had a Public variable inside
the interface, how would that be different than in Abstract Class?

Le variabili nelle interfacce sono, per impostazione predefinita, pubbliche statiche e finali. La domanda potrebbe essere inquadrata come se tutte le variabili nella classe astratta fossero pubbliche? Bene, possono ancora essere non statici e non finali a differenza delle variabili nelle interfacce.

Infine aggiungerei un altro punto a quelli sopra menzionati: le classi astratte sono ancora classi e rientrano in un singolo albero ereditario mentre le interfacce possono essere presenti in eredità multipla.


13
  1. Interfaccia:
    • Non implementiamo (o definiamo) metodi, lo facciamo in classi derivate.
    • Non dichiariamo variabili membro nelle interfacce.
    • Le interfacce esprimono la relazione HAS-A. Ciò significa che sono una maschera di oggetti.
  2. Classe astratta:
    • Possiamo dichiarare e definire metodi in classe astratta.
    • Ne nascondiamo i costruttori. Ciò significa che non vi è alcun oggetto creato da esso direttamente.
    • La classe astratta può contenere variabili membro.
    • Le classi derivate ereditano la classe astratta che significa che gli oggetti delle classi derivate non sono mascherati, ma ereditano nella classe astratta. La relazione in questo caso è IS-A.

Questa è la mia opinione.


12

Copiato da CLR via C # da Jeffrey Richter ...

Sento spesso la domanda "Devo progettare un tipo di base o un'interfaccia?" La risposta non è sempre chiara.

Ecco alcune linee guida che potrebbero aiutarti:

■■ Rapporto IS-A vs. CAN-DO Un tipo può ereditare una sola implementazione. Se il tipo derivato non può rivendicare una relazione IS-A con il tipo base, non utilizzare un tipo base; usa un'interfaccia. Le interfacce implicano una relazione CAN-DO. Se la funzionalità CAN-DO sembra appartenere a vari tipi di oggetti, utilizzare un'interfaccia. Ad esempio, un tipo può convertire istanze di se stesso in un altro tipo (IConvertible), un tipo può serializzare un'istanza di se stesso (ISerializable), ecc. Si noti che i tipi di valore devono essere derivati ​​da System.ValueType e, pertanto, non possono essere derivati da una classe base arbitraria. In questo caso, è necessario utilizzare una relazione CAN-DO e definire un'interfaccia.

■■ Facilità d'uso In generale, per lo sviluppatore è più semplice definire un nuovo tipo derivato da un tipo base piuttosto che implementare tutti i metodi di un'interfaccia. Il tipo di base può fornire molte funzionalità, quindi probabilmente il tipo derivato necessita solo di modifiche relativamente piccole al suo comportamento. Se si fornisce un'interfaccia, il nuovo tipo deve implementare tutti i membri.

■■ Implementazione coerente Non importa quanto bene sia documentato un contratto di interfaccia, è molto improbabile che tutti implementino correttamente il contratto al 100%. In effetti, COM soffre di questo problema, motivo per cui alcuni oggetti COM funzionano correttamente solo con Microsoft Word o Windows Internet Explorer. Fornendo un tipo base con una buona implementazione di default, inizi usando un tipo che funziona ed è ben testato; è quindi possibile modificare le parti che richiedono modifiche.

■■ Versioning Se si aggiunge un metodo al tipo base, il tipo derivato eredita il nuovo metodo, si inizia utilizzando un tipo che funziona e non è necessario ricompilare il codice sorgente dell'utente. L'aggiunta di un nuovo membro a un'interfaccia forza l'erede dell'interfaccia a modificare il suo codice sorgente e ricompilare.


1
@AbdullahShoaib è -a e chiunque-può-fare ma non può-fare, c'è una differenza qui. questa è la ragione di base, abbiamo bisogno dell'interfaccia. Anche il comportamento da fare farà parte abstract class.
Scambio eccessivo del

10

Un'interfaccia definisce un contratto per un servizio o un insieme di servizi. Forniscono polimorfismo in modo orizzontale in quanto due classi completamente non correlate possono implementare la stessa interfaccia ma possono essere utilizzate in modo intercambiabile come parametro del tipo di interfaccia che implementano, poiché entrambe le classi hanno promesso di soddisfare l'insieme di servizi definito dall'interfaccia. Le interfacce non forniscono dettagli di implementazione.

Una classe astratta definisce una struttura di base per le sue sottoclassi e, facoltativamente, un'implementazione parziale. Le classi astratte forniscono polimorfismo in modo verticale, ma direzionale, in quanto qualsiasi classe che eredita la classe astratta può essere trattata come un'istanza di quella classe astratta ma non viceversa. Le classi astratte possono e spesso contengono dettagli di implementazione, ma non possono essere istanziate da sole - solo le loro sottoclassi possono essere "rinnovate".

C # consente anche l'ereditarietà dell'interfaccia, sia chiaro.


1
L'uso dei termini orizzontale e verticale ha reso molto chiaro immaginare la differenza.
Infinito

10

La maggior parte delle risposte si concentra sulla differenza tecnica tra la classe astratta e l'interfaccia, ma dal momento che tecnicamente un'interfaccia è fondamentalmente una sorta di classe astratta (una senza dati o implementazione), penso che la differenza concettuale sia molto più interessante e potrebbe essere ciò che gli intervistatori sono dopo.

Un interfaccia è un contratto . Specifica: "questo è il modo in cui ci parleremo". Non può avere alcuna implementazione perché non dovrebbe avere alcuna implementazione. È un contratto È come i .hfile di intestazione in C.

Una classe astratta è un'implementazione incompleta . Una classe può o meno implementare un'interfaccia e una classe astratta non deve implementarla completamente. Una classe astratta senza alcuna implementazione è un po 'inutile, ma totalmente legale.

Fondamentalmente qualsiasi classe, astratta o no, riguarda ciò che è , mentre un'interfaccia riguarda il modo in cui la usi . Ad esempio: Animalpotrebbe essere una classe astratta che implementa alcune funzioni metaboliche di base e che specifica metodi astratti per la respirazione e la locomozione senza dare un'implementazione, perché non ha idea se debba respirare attraverso branchie o polmoni e se vola, nuota, cammina o crawl. Mountd'altra parte, potrebbe essere un'interfaccia, che specifica che puoi cavalcare l'animale, senza sapere che tipo di animale è (o se è affatto un animale!).

Il fatto che dietro le quinte, un'interfaccia sia sostanzialmente una classe astratta con solo metodi astratti, non importa. Concettualmente, ricoprono ruoli totalmente diversi.


10

Poiché avresti potuto ottenere le conoscenze teoriche dagli esperti, non sto spendendo molte parole nel ripetere tutte quelle qui, piuttosto lasciami spiegare con un semplice esempio in cui possiamo usare / non usare Interfacee Abstract class.

Considera che stai progettando un'applicazione per elencare tutte le funzionalità di Cars. In vari punti hai bisogno dell'eredità in comune, poiché alcune delle proprietà come DigitalFuelMeter, Air Conditioning, Adjustment seat, ecc. Sono comuni per tutte le auto. Allo stesso modo, abbiamo bisogno dell'eredità per alcune classi solo perché alcune delle proprietà come il sistema di frenatura (ABS, EBD) sono applicabili solo per alcune auto.

La classe sottostante funge da classe base per tutte le auto:

public class Cars
{
    public string DigitalFuelMeter()
    {
        return "I have DigitalFuelMeter";
    }

    public string AirCondition()
    {
        return "I have AC";
    }

    public string SeatAdjust()
    {
        return "I can Adjust seat";
    }
}

Considera che abbiamo una classe separata per ogni auto.

public class Alto : Cars
{
    // Have all the features of Car class    
}

public class Verna : Cars
{
    // Have all the features of Car class + Car need to inherit ABS as the Braking technology feature which is not in Cars        
}

public class Cruze : Cars
{
    // Have all the features of Car class + Car need to inherit EBD as the Braking technology feature which is not in Cars        
}

Considera che abbiamo bisogno di un metodo per ereditare la tecnologia di frenata per le auto Verna e Cruze (non applicabile per Alto). Sebbene entrambi utilizzino la tecnologia di frenata, la "tecnologia" è diversa. Quindi stiamo creando una classe astratta in cui il metodo sarà dichiarato come Astratto e dovrebbe essere implementato nelle sue classi figlio.

public abstract class Brake
{
    public abstract string GetBrakeTechnology();
}

Ora stiamo provando a ereditare da questa classe astratta e il tipo di sistema di frenatura è implementato in Verna e Cruze:

public class Verna : Cars,Brake
{
    public override string GetBrakeTechnology()
    {
        return "I use ABS system for braking";
    }       
}

public class Cruze : Cars,Brake
{
    public override string GetBrakeTechnology()
    {
       return "I use EBD system for braking";
    }         
}

Vedi il problema nelle due classi precedenti? Esse ereditano da più classi che C # .Net non consente anche se il metodo è implementato nei figli. Qui nasce la necessità di Interface.

interface IBrakeTechnology
{
    string GetBrakeTechnology();
}

E l'implementazione è riportata di seguito:

public class Verna : Cars, IBrakeTechnology
{
    public string GetBrakeTechnology()
    {
        return "I use ABS system for braking";
    }
}

public class Cruze : Cars, IBrakeTechnology
{
   public string GetBrakeTechnology()
   {
       return "I use EBD system for braking";
   }        
}

Ora Verna e Cruze possono ottenere l'eredità multipla con il proprio tipo di tecnologie di frenatura con l'aiuto di Interface.


4
Questa è una delle migliori spiegazioni a causa degli esempi.
Adam Mendoza,

2
Questo ha senso per me senza tormentare il cervello. Stavo solo cercando di trovare un esempio di auto per i miei studenti. Grazie per il tempo dedicato a metterlo insieme.
tazboy,

9

Le interfacce sono un modo leggero per applicare un comportamento particolare. Questo è un modo di pensare.


8

Queste risposte sono troppo lunghe.

  • Le interfacce servono per definire i comportamenti.

  • Le classi astratte servono a definire una cosa stessa, compresi i suoi comportamenti. Ecco perché a volte creiamo una classe astratta con alcune proprietà extra che ereditano un'interfaccia.

Questo spiega anche perché Java supporta solo l'ereditarietà singola per le classi ma non pone restrizioni alle interfacce. Perché un oggetto concreto non può essere cose diverse, ma può avere comportamenti diversi.


7

1) Un'interfaccia può essere vista come una pura classe astratta, è la stessa, ma nonostante ciò, non è la stessa cosa per implementare un'interfaccia ed ereditare da una classe astratta. Quando erediti da questa pura classe astratta stai definendo una gerarchia -> eredità, se implementi l'interfaccia che non sei, e puoi implementare tutte le interfacce che vuoi, ma puoi ereditare solo da una classe.

2) Puoi definire una proprietà in un'interfaccia, quindi la classe che implementa quell'interfaccia deve avere quella proprietà.

Per esempio:

  public interface IVariable
  {
      string name {get; set;}
  }

La classe che implementa tale interfaccia deve avere una proprietà simile.


7

Sebbene questa domanda sia piuttosto vecchia, vorrei aggiungere un altro punto a favore delle interfacce:

Le interfacce possono essere iniettate utilizzando qualsiasi strumento di Iniezione delle dipendenze dove l'iniezione di classe Abstract è supportata da pochissimi.


1
Credo che intendi dire che uno strumento DI può iniettare una classe che implementa un'interfaccia. Alcuni di questi strumenti possono anche iniettare classi derivate da una classe astratta o stai dicendo che è impossibile?
John Saunders,

6

Da un'altra mia risposta , trattando principalmente quando usare l'uno contro l'altro:

Nella mia esperienza, le interfacce sono utilizzate al meglio quando si hanno diverse classi, ognuna delle quali deve rispondere allo stesso metodo o ai metodi in modo che possano essere utilizzate in modo intercambiabile con altri codici che verranno scritti sull'interfaccia comune di quelle classi. Il miglior uso di un'interfaccia è quando il protocollo è importante ma la logica sottostante può essere diversa per ogni classe. Se altrimenti dovresti duplicare la logica, considera invece le classi astratte o l'ereditarietà delle classi standard.


6

Tipi di interfaccia vs. classi di base astratte

Adattato da Pro C # 5.0 e dal libro .NET 4.5 Framework .

Il tipo di interfaccia potrebbe sembrare molto simile a una classe base astratta. Ricordiamo che quando una classe è contrassegnata come astratta, può definire un numero qualsiasi di membri astratti per fornire un'interfaccia polimorfica a tutti i tipi derivati. Tuttavia, anche quando una classe definisce un insieme di membri astratti, è anche libero di definire un numero qualsiasi di costruttori, dati di campo, membri non astratti (con implementazione) e così via. Le interfacce, d'altra parte, contengono solo definizioni di membri astratte. L'interfaccia polimorfica stabilita da una classe genitore astratta soffre di una grande limitazione in quanto solo i tipi derivati ​​supportano i membri definiti dal genitore astratto. Tuttavia, nei sistemi software più grandi, è molto comune sviluppare gerarchie di classi multiple che non hanno un genitore comune oltre System.Object. Dato che i membri astratti in una classe base astratta si applicano solo ai tipi derivati, non abbiamo modo di configurare i tipi in gerarchie diverse per supportare la stessa interfaccia polimorfica. A titolo di esempio, supponiamo di aver definito la seguente classe astratta:

public abstract class CloneableType
{
// Only derived types can support this
// "polymorphic interface." Classes in other
// hierarchies have no access to this abstract
// member.
   public abstract object Clone();
}

Data questa definizione, solo i membri che estendono CloneableType sono in grado di supportare il metodo Clone (). Se si crea un nuovo set di classi che non estende questa classe base, non è possibile ottenere questa interfaccia polimorfica. Inoltre, è possibile ricordare che C # non supporta l'ereditarietà multipla per le classi. Pertanto, se si desidera creare un MiniVan che è -Auto ed è -Con CloneableType, non è possibile farlo:

// Nope! Multiple inheritance is not possible in C#
// for classes.
public class MiniVan : Car, CloneableType
{
}

Come indovineresti, i tipi di interfaccia vengono in soccorso. Dopo che è stata definita un'interfaccia, può essere implementata da qualsiasi classe o struttura, in qualsiasi gerarchia, all'interno di qualsiasi spazio dei nomi o qualsiasi assembly (scritto in qualsiasi linguaggio di programmazione .NET). Come puoi vedere, le interfacce sono altamente polimorfiche. Considera l'interfaccia .NET standard denominata ICloneable, definita nello spazio dei nomi di sistema. Questa interfaccia definisce un singolo metodo chiamato Clone ():

public interface ICloneable
{
object Clone();
}

6

Risposta alla seconda domanda: la publicvariabile definita in interfaceè static finaldi default mentre la publicvariabile in abstractclasse è una variabile di istanza.


6

Sicuramente è importante capire il comportamento dell'interfaccia e della classe astratta in OOP (e come le lingue li gestiscono), ma penso che sia anche importante capire cosa significhi esattamente ogni termine. Riesci a immaginare che il ifcomando non funzioni esattamente come il significato del termine? Inoltre, in realtà alcune lingue stanno riducendo, ancora di più, le differenze tra un'interfaccia e un abstract ... se per caso un giorno i due termini operano in modo quasi identico, almeno puoi definire te stesso dove (e perché) dovrebbero esserci usato per.

Se leggi alcuni dizionari e altri caratteri potresti trovare significati diversi per lo stesso termine ma avere alcune definizioni comuni. Penso che questi due significati che ho trovato in questo sito siano davvero buoni e adatti.

Interfaccia:

Una cosa o circostanza che consente a elementi separati e talvolta incompatibili di coordinarsi efficacemente.

Astratto:

Qualcosa che concentra in sé le qualità essenziali di qualcosa di più ampio o più generale, o di diverse cose; essenza.

Esempio:

Hai comprato un'auto e ha bisogno di carburante.

inserisci qui la descrizione dell'immagine

Il tuo modello di auto è XYZ, che è di genere ABC, quindi è un'auto di cemento, un'istanza specifica di un'auto. Una macchina non è un oggetto reale. In effetti, è un insieme astratto di standard (qualità) per creare un oggetto specifico. In breve, Car è una classe astratta , è "qualcosa che concentra in sé le qualità essenziali di qualcosa di più ampio o più generale" .

L'unico carburante che corrisponde alle specifiche del manuale dell'auto deve essere utilizzato per riempire il serbatoio dell'auto. In realtà, non c'è nulla che ti limiti a mettere qualsiasi carburante, ma il motore funzionerà correttamente solo con il carburante specificato, quindi è meglio seguire i suoi requisiti. I requisiti dicono che accetta, come altre auto dello stesso genere ABC, un set standard di carburante.

In una visione orientata agli oggetti, il carburante per il genere ABCnon dovrebbe essere dichiarato come classe perché non esiste carburante concreto per un genere specifico di auto. Sebbene la tua auto possa accettare un carburante o un carburante di classe astratta, devi ricordare che solo alcuni dei carburanti per veicoli esistenti soddisfano le specifiche, quelli che implementano i requisiti nel manuale della tua auto. In breve, dovrebbero implementare l' interfaccia ABCGenreFuel , che "... consente a elementi separati e talvolta incompatibili di coordinarsi efficacemente" .

appendice

Inoltre, penso che dovresti tenere a mente il significato del termine class, che è (dallo stesso sito menzionato in precedenza):

Classe:

Un numero di persone o cose considerate formare un gruppo a causa di attributi, caratteristiche, qualità o tratti comuni; genere;

In questo modo, una classe (o classe astratta) non dovrebbe rappresentare solo attributi comuni (come un'interfaccia), ma una sorta di gruppo con attributi comuni. Un'interfaccia non deve rappresentare un tipo. Deve rappresentare attributi comuni. In questo modo, penso che le classi e le classi astratte possano essere usate per rappresentare cose che non dovrebbero cambiare spesso i suoi aspetti, come un essere umano un mammifero, perché rappresenta alcuni tipi. I tipi non dovrebbero cambiare se stessi così spesso.


1
troppa lanugine, non farlo sembrare più confuso per le persone di quanto potrebbe già essere.
Ganjeii,

5

Dalla prospettiva di codifica

Un'interfaccia può sostituire una classe astratta se la classe astratta ha solo metodi astratti. Altrimenti, cambiare la classe Abstract in interfaccia significa che perderai la riusabilità del codice fornita da Inheritance.

Dal punto di vista del design

Tienilo come una classe astratta se è una relazione "È un" e hai bisogno di un sottoinsieme o di tutte le funzionalità. Tienilo come interfaccia se è una relazione "Dovresti fare".

Decidi ciò di cui hai bisogno: solo l'applicazione della politica o la riutilizzabilità del codice E la politica.


3

Coppia di altre differenze:

Le classi astratte possono avere metodi, proprietà, campi ecc. Statici e gli operatori, le interfacce no. L'operatore Cast consente il casting da / verso la classe astratta ma non consente il casting da / verso l'interfaccia.

Praticamente puoi usare la classe astratta da sola anche se non viene mai implementata (attraverso i suoi membri statici) e non puoi usare l'interfaccia da sola in alcun modo.


in Java, l'interfaccia può avere una variabile membro ma per impostazione predefinita diventa pubblica statica .. così l'interfaccia può avere campi statici
Jitendra Vispute,

Sì, l'interfaccia può avere campi statici. MA l'interfaccia non può avere metodi statici.
uno studente il
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.