Se implemento un'interfaccia, si chiama eredità?


31

Se la mia classe è implementsun'interfaccia, allora posso dire che sto seguendo l'eredità? So che quando una classe è extendsun'altra, allora è eredità.



7
Il commento di Jodrell è semplicemente sbagliato. L'implementazione di un'interfaccia è davvero eredità, e ereditare un'interfaccia da un'altra è eredità. Come lo sappiamo? Definendo la parola che stiamo usando. L'ereditarietà è la proprietà che i membri ereditabili di un tipo sono anche membri di un altro tipo. Con questa definizione, chiaramente una classe che implementa un'interfaccia ha ereditato tutti i metodi dell'interfaccia; basta guardare la classe e l'interfaccia e scoprirai che in un programma corretto hanno gli stessi membri.
Eric Lippert,

Ho deselezionato e lasciato con più confusione.
RajeeV VenkaT

18
Per quello che vale, penso che stai spendendo molto tempo su una definizione di parola che non ti darà molti benefici. Alla fine, sappiamo tutti cosa significa implementare un'interfaccia e se è considerata "eredità" è in gran parte irrilevante per il tuo lavoro quotidiano.
Robert Harvey,

3
Sono (principalmente) d'accordo con Robert. Penso che ci sia un reale valore nella comprensione dei significati tecnici precisi delle parole gergali in quanto vengono utilizzati in vari contesti. Ma Robert ha ragione nel capire che l'impatto pratico è di grande beneficio! Come puoi usare l'ereditarietà per rendere il tuo codice più sicuro? Più testabile? Più riutilizzabile? Più flessibile? E così via. Sapere che i membri dei tipi di base sono anche membri dei tipi derivati ​​è fantastico, ma è ancora meglio sapere come usarlo in modo efficace.
Eric Lippert,

Risposte:


78

AGGIORNAMENTO: ho rivisto questa risposta. Numerosi punti positivi sono stati sollevati nei commenti che meritavano di essere richiamati.

Se la mia classe implementa un'interfaccia, allora posso dire che sto seguendo l'eredità?

Non è del tutto chiaro cosa intendi per "seguire l'eredità". Facciamo una domanda leggermente diversa?

Che cos'è l'eredità?

  • Quando i membri di un tipo X sono considerati membri di un altro tipo Y, i membri di Y vengono ereditate da X .
  • Esiste una relazione ereditaria tra alcuni tipi; cioè per alcuni tipi X e Y diciamo "Y eredita da X".

Questi sono leggermente diversi. Questo è un peccato perché è confuso.

Quali confusioni derivano tipicamente da questa sottile distinzione?

La confusione può sorgere perché le persone pensano all'eredità come un meccanismo per condividere i dettagli dell'implementazione. Anche se è un tale meccanismo, che meccanismo funziona attraverso la condivisione di membri . Quei membri non devono avere implementazioni! Come vedremo, possono essere astratti.

Personalmente sarei più felice se le specifiche Java e C # usassero una parola diversa da "eredita" per descrivere la relazione tra metodi di interfaccia e classi, per evitare questa confusione. Ma non lo fanno, e dobbiamo ragionare dalle specifiche, non contro di loro.

In Java, i membri dell'interfaccia sono ereditati dalle classi che li implementano?

Sì, alcuni lo sono. Vedere la sezione delle specifiche Java 8.4.8, che cito qui per comodità.

Una classe C eredita dalla sua superclasse diretta e dalle superinterfacce dirette tutti i metodi astratti e predefiniti m per i quali sono vere tutte le seguenti condizioni: [...]

Se dici che una classe implementa un'interfaccia, la classe eredita i metodi astratti e predefiniti di tale interfaccia . (Naturalmente ho omesso le condizioni che seguono; vedere le specifiche per i dettagli. In particolare, una classe che implementa un membro di un'interfaccia non è considerata ereditata da quel membro. Ancora una volta, è confuso? Sì.)

Generalmente in Java diciamo che una classe eredita da un'interfaccia?

In genere si direbbe che una classe implementa un'interfaccia. Come notato sopra, una classe può ereditare i membri da un'interfaccia e tuttavia non si può dire che erediti dall'interfaccia. Il che è confuso, sì.

Questa sottile distinzione è importante nel lavoro quotidiano?

In genere no. Questo tipo di analisi ristretta delle specifiche è più utile per gli autori di compilatori che per gli sviluppatori della linea di business. È più importante capire quando utilizzare un'interfaccia piuttosto che ottenere una definizione precisa di "eredita da".


4
Non posso discutere con un riferimento canonico. Quando le specifiche differiscono, come necessariamente fanno, i termini semplici diventano semanticamente sovraccarichi e ambigui fuori dal contesto. La domanda è taggata con javaquindi questa è la risposta giusta, a meno che OP non abbia significato qualcos'altro java:-)
Jodrell

5
Sebbene la domanda sia taggata con Java, trovo problematico citare una specifica del linguaggio per un termine generico. Molte lingue hanno interfacce e le loro specifiche di lingua possono usare un termine diverso, quindi l'uso di un termine specifico di Java può essere fonte di confusione quando si parla con sviluppatori che usano X-Lang.
Thomas Owens

5
@ThomasOwens: sono d'accordo sul fatto che questo scenario sia comune e non sono completamente d'accordo con la tua conclusione. La soluzione al problema di comunicazione che descrivi è educare tutti i soggetti coinvolti ai significati precisi delle parole nel contesto pertinente . Esistono specifiche per fornire questa chiarezza; usali!
Eric Lippert,

5
Perché la specifica del linguaggio Java dovrebbe dire l'ultima parola qui? Le specifiche del linguaggio spesso sostengono cose con cui lo "sviluppatore comune" non è d'accordo sulla terminologia.
Benjamin Gruenbaum,

5
@BenjaminGruenbaum: non lo so. Questi sviluppatori hanno torto e spesso si assumono la responsabilità di "educare" gli altri sulle loro convinzioni sbagliate. Non crederesti al numero di libri sul linguaggio di programmazione che ho dovuto correggere perché gli autori avevano delle convinzioni completamente pazze su VB, C #, JavaScript, ecc., Che non erano affatto corrette. (Jon Skeet non era tra questi; C # In profondità era corretto dall'inizio! Non ho mai fatto così pochi commenti su un libro e sono stato ancora pagato.)
Eric Lippert

26

Ereditarietà significa scrivere una nuova sottoclasse per una superclasse. Scrivere una nuova classe su un'interfaccia significa implementare quell'interfaccia. (E scrivere una nuova interfaccia basata su una vecchia sta estendendo tale interfaccia.)

L'unico termine corretto che si applica a tutte e tre le possibilità è il sottotipo . Non ogni sottotipo è una sottoclasse.


1
Il libro GoF sembra considerare il termine di ereditarietà dell'interfaccia appropriato per descrivere il sottotipo (Sezione 1.6 Classe contro ereditarietà dell'interfaccia)
moscerino

"Una volta ho partecipato a una riunione del gruppo di utenti Java in cui James Gosling (l'inventore di Java) era il relatore in primo piano. Durante la memorabile sessione di domande e risposte, qualcuno gli ha chiesto:" Se potessi fare di nuovo Java, cosa cambieresti? "" tralascia le classi ", ha risposto. Ha spiegato che il vero problema non erano le classi in sé, ma piuttosto l'ereditarietà dell'implementazione (la relazione estesa). L'ereditarietà dell'interfaccia (la relazione implementa) è preferibile. Dovresti evitare l'ereditarietà dell'implementazione ogni volta che è possibile." javaworld.com/article/2073649/core-java/…
ricardoramos

1

Con le sottoclassi , tu

  • eredita lo stato della superclasse (tutte le variabili di istanza, che tu le veda o meno)
  • ereditare implementazioni effettive (tutti i metodi non astratti)

Con le interfacce , si completa un contratto implementando i metodi dichiarati.

Questo è il modo classico di vederlo. Ora con Java 8 le interfacce diventano una miscela:

  • non erediti ancora lo stato (poiché le interfacce non hanno ancora variabili di istanza)
  • ora puoi ereditare le implementazioni predefinite dall'interfaccia

L'implementazione di un'interfaccia i cui metodi hanno tutte implementazioni predefinite continuerebbe a essere considerata come "implement", o piuttosto come estensione? Non saprei dirlo. Dato che questo caso è piuttosto inverosimile (questo abilitava la multi-ereditarietà senza stato), userei comunque l'ereditarietà solo con le sottoclassi.

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.