Domanda

Perché vengono create le classi astratte o di interfaccia o quando dovremmo usare le classi astratte o di interfaccia?

È stato utile?

Soluzione

L'interfaccia viene utilizzata quando si desidera dichiarare solo quali metodi e membri DEVE avere una classe. Chiunque implementa l'interfaccia dovrà dichiarare e implementare i metodi elencati dall'interfaccia.

Se si desidera avere anche un'implementazione predefinita, utilizzare la classe astratta. Qualsiasi classe che estenda la classe astratta dovrà implementare solo i suoi metodi e membri astratti e avrà una implementazione predefinita degli altri metodi della classe astratta, che puoi ignorare o meno.

--EDIT - ho dimenticato di menzionare, mi ha ricordato Earwicker

Infine, puoi implementare tutte le interfacce che vuoi, ma estendere solo una classe (che sia astratta o no). Tienilo a mente prima di scegliere.

Altri suggerimenti

La differenza chiave è che puoi implementare più interfacce in una classe, ma solo estende una singola classe astratta. Questo perché una classe astratta può anche definire campi che memorizzano dati, mentre un'interfaccia non può.

Una classe astratta è una classe, che ha almeno un metodo astratto oppure puoi anche rendere tutti i tuoi metodi come astratti. Ovviamente non può essere istanziato. Devi ereditare da una classe astratta e implementare i metodi astratti nella classe ereditaria (cioè la classe che estende la classe astratta).

Le interfacce non sono affatto classi (quindi non chiamarle classe di interfaccia). Le interfacce definiscono la firma dei metodi senza alcuna implementazione. Inoltre le interfacce non hanno campi membri. Se si implementa un'interfaccia in una classe, è necessario fornire implementazioni per tutti i metodi forniti dall'interfaccia.

Ha senso definire un'API generalizzata per alcune cose, che possono avere implementazioni completamente diverse. Le classi astratte sono più utili per le classi che fanno principalmente lo stesso, ma presentano alcune sottili differenze. Puoi combinare entrambi gli approcci.

Un buon esempio è il framework delle collezioni della libreria di classi Java. Hai la lista delle interfacce, che definisce come le liste devono comportarsi. Alcune implementazioni sono ad esempio ArrayList e LinkedList. Poiché si comportano in modo simile, le cose che funzionano allo stesso modo per entrambi sono implementate nella classe astratta AbstactList, entrambe ereditano questo.

Vedi L'interfaccia è fondamentalmente un "Contratto". Quando si definisce un'interfaccia, si definisce un contratto. Laddove le classi astratte vengono estese, vengono implementate le interfacce.

Consideriamo un esempio.

public interface Friend {
void hello();
}

Ora hai definito un contratto che dice che qualsiasi classe che vuole implementare Friend deve fornire una definizione per il metodo hello () .

Ecco un'implementazione:

public class myFriend implements Friend {
public void hello()
println("Done");
}

Ora myFriend ha adempiuto al contratto. Ora la domanda è: dove utilizzare le interfacce?

Le interfacce ti aiutano a definire un comportamento che deve essere implementato. Supponi di avere una classe A che definisce alcune funzionalità. Si desidera che le altre classi utilizzino questa funzionalità di classe solo se definiscono un comportamento particolare (metodi). Imponi questa limitazione in termini di interfaccia.

SamuelCarrijo sembra aver risposto bene a questa domanda.

Inoltre per Java, alcuni framework richiedono un'interfaccia con cui lavorare. Sto pensando a (diciamo) proxy dinamici o alcuni framework di proxy client / server. Questo perché usano l'introspezione sull'oggetto per determinare i metodi implementati dalle interfacce implementate dall'oggetto. Quindi di tanto in tanto devi implementare un'interfaccia per un oggetto in cui, forse, non ti preoccuperesti normalmente.

Nota questo motivo delle interfacce è specifico di Java.

Le classi astratte vengono utilizzate quando si crea una gerarchia di ereditarietà. Tuttavia, la maggior parte delle gerarchie ereditarie non dovrebbe essere troppo "profonda" (ovvero troppi livelli di eredità). Molti libri di design orientati agli oggetti favoriranno le interfacce rispetto all'ereditarietà (un libro che ho letto una volta ha citato uno sviluppatore dicendo che "l'ereditarietà è la caratteristica più semplice [orientata agli oggetti] che non implementerai"), in quanto ciò consente alle classi di essere assegnate comportamenti "per contratto", dove il contratto è l'interfaccia.

Vale la pena notare la risposta di samuelcarrijo: se si desidera avere un'implementazione predefinita di un metodo, è necessario utilizzare una classe astratta che abbia un'implementazione concreta del metodo per dargli un'implementazione predefinita. Questa implementazione predefinita può essere ignorata nelle classi secondarie.

Spero che questo aiuti!

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top