2013-03-06 18 views
7

Non sto chiedendo le differenze tra questi due, ma perché le interfacce sono più spesso preferite al posto delle classi astratte.Perché è preferibile utilizzare le interfacce anziché le classi astratte?

+9

Dice chi, esattamente? – Oded

+0

Nessun dubbio. Mi piacciono le classi astratte ... Trovo noiose le interfacce. Hanno il loro scopo, ma causano un grave gonfiore del codice quando vengono usati impropriamente. –

+0

Non sono necessariamente preferiti, hanno usi diversi. –

risposta

14

La "mancanza" più ovvia delle classi astratte è che i tipi ereditari possono ereditare solo da una singola classe astratta.

Quando si tratta di interfacce, è possibile implementare più interfacce.

Quindi, quando si progettano i tipi in modo da implementare più contratti, le interfacce sono semplicemente l'unica opzione.

Quindi, almeno nel mondo C#, questo, in combinazione con i principi SOLID, può spiegare la propensione verso le interfacce.

+0

+1 per il riferimento SOLID :) –

+0

Risposta molto buona - grazie. –

4

Come regola generale, utilizziamo le interfacce quando non abbiamo nulla da dire sull'implementazione e sulle classi astratte quando abbiamo almeno un'implementazione parziale.

2

Qui è la mia regola empirica che ho trovato la maggior parte d'accordo con:

  • Inizia con una classe concreta. Non v'è alcuna necessità di astratto nulla se non sta andando mai essere necessario
  • Sposta in un'astrazione se si trova il bisogno

Una volta che ci si sposta verso l'astrazione, si può decidere quale tipo tramite questa nota: non è possibile ereditate da più classi astratte, quindi è così che dovreste davvero decidere tra una classe astratta o un'interfaccia IMO, in più se avete bisogno di un'implementazione o meno (se non lo sono, quindi usate semplicemente un'interfaccia per evitare il multiplo potenziale di conflitto ereditario più avanti)

+0

Ma se stai facendo test unitari e hai bisogno di rendere la tua classe testabile e quindi mockable non dovresti creare un'interfaccia dalla classe con cui iniziare? –

+2

Perché? Se stai per passare questo in un'altra classe come dipendenza, allora sì puoi creare un'interfaccia. Ma, allo stesso tempo, puoi semplicemente rendere i tuoi metodi virtuali e quindi irrintracciabili. Se stai testando la classe stessa, allora non vuoi farne una simulazione, vuoi l'effettiva implementazione in quanto è ciò che stai testando. Non è necessario saltare prima a un'astrazione se non è necessario. Vai con semplicità prima e refactoring se necessario. –

5

ho intenzione di fare l'avvocato del diavolo qui ...

Un vantaggio che ABC ha sulle interfacce è che è possibile aggiungere metodi a un ABC senza rompere tutte le classi derivate. Se si aggiunge un metodo a un'interfaccia, si interromperà ogni singola classe che implementa tale interfaccia.

Il consiglio di Microsoft è favour classes over interfaces per questo motivo.

Inoltre, un ABC può fornire un'implementazione predefinita per i suoi metodi, laddove appropriato.

Inoltre, un ABC può definire tipi (come enumerazioni) e readonly 'costanti', mentre un'interfaccia non può.

1

Se si dispone di un tipo che può essere progettato come un'interfaccia o una classe astratta, perché scegliere una classe astratta?

In questo senso, usiamo solo classe astratta quando alcune funzioni non può essere fatto in Interfaccia:

  1. Stato. sebbene un'interfaccia possa chiedere alle sottoclassi di implementare lo stato, potrebbe essere più comodo usare una super classe astratta per mantenere lo stato.

  2. accesso limitato utente a protected. mentre tutte le cose nell'interfaccia sono public

  3. metodi statici.(si noti che in Java 8, probabilmente, l'interfaccia può avere metodi statici)

  4. metodi concreti con implementazioni. (notare che in Java 8, i metodi di interfaccia possono avere defualt impl)

  5. aggiungere altri metodi concreti senza interrompere sottoclassi. (nota che in Java 8, possiamo aggiungere più metodi a un'interfaccia esistente se i metodi hanno impli predefiniti)

5

È davvero una domanda molto carica. Entrambi hanno i loro rispettivi usi in diverse situazioni.

classi astratte

una classe astratta viene utilizzata quando v'è una funzionalità comune da condividere tra le sottoclassi, ma la superclasse in sé non esisterà mai. Ad esempio, una classe Person non esisterà mai. Tuttavia una classe Woman sarà. Invece di ripetere tutti i metodi presenti in , in Man, Boy e Girl, semplicemente lo si eleva alla superclasse, in modo che tutti abbiano accesso a questa funzionalità e possano ignorare i metodi che desiderano eseguire in modo diverso.

Interfacce

interfacce vengono utilizzate quando v'è un requisito. Il modo in cui li guardo è come un contratto. L'accordo è che qualsiasi classe che implementa l'interfaccia, dovrà fornire il codice per un certo numero di metodi.

Ad esempio, è possibile generare una classe Rock e una classe Ball. Invece del metodo per lanciare una palla dovendo prendere in considerazione ogni oggetto che può essere lanciato, se ogni oggetto implementa l'interfaccia ThrowingItem (non volevo usare la parola Throwable per ovvi motivi), allora il metodo può solo accettare un oggetto del tipo ThrowingItem e sa per certo che i metodi concordati saranno lì.

Ciò consente l'accoppiamento lento tra il metodo throw e le classi che lo utilizzano, poiché tutte le comunicazioni avvengono tramite l'interfaccia.


Come potete vedere, i due diversi tipi sono usati in situazioni molto diverse, e confrontarli è davvero come confrontare mele e arance.

Problemi correlati