Spiegazione della definizione di ereditarietà dell'interfaccia come descritto nel libro GoF

3

Sto leggendo il primo capitolo del libro Gof . La sezione 1.6 discute sull'ereditarietà della classe vs dell'interfaccia:

Ereditarietà della classe contro l'interfaccia

It's important to understand the difference between an object's class and its type. An object's class defines how the object is implemented.The class defines the object's internal state and the implementation of its operations.In contrast,an object's type only refers to its interface--the set of requests on which it can respond. An object can have many types, and objects of different classes can have the same type.

Of course, there's a close relationship between class and type. Because a class defines the operations an object can perform, it also defines the object's type . When we say that an object is an instance of a class, we imply that the object supports the interface defined by the class.

Languages like c++ and Eiffel use classes to specify both an object's type and its implementation. Smalltalk programs do not declare the types of variables; consequently,the compiler does not check that the types of objects assigned to a variable are subtypes of the variable's type. Sending a message requires checking that the class of the receiver implements the message, but it doesn't require checking that the receiver is an instance of a particular class.

It's also important to understand the difference between class inheritance and interface inheritance (or subtyping). Class inheritance defines an object's implementation in terms of another object's implementation. In short, it's a mechanism for code and representation sharing. In contrast,interface inheritance(or subtyping) describes when an object can be used in place of another.

Ho familiarità con il linguaggio di programmazione Java e JavaScript e non ho familiarità con C ++ o Smalltalk o Eiffel come menzionato qui. Quindi sto cercando di mappare i concetti discussi qui sul modo di fare classi, ereditarietà e interfacce di Java.

Ecco come penso a questi concetti in Java:

In Java una classe è sempre un progetto per gli oggetti che produce e quale interfaccia (come in "insieme di tutte le possibili richieste a cui l'oggetto può rispondere") un oggetto di quella classe in possesso è definito durante la fase di compilazione solo perché il la classe dell'oggetto avrebbe implementato quelle interfacce. Le richieste a cui un oggetto di quella classe può rispondere è l'insieme di tutti i metodi presenti nella classe (compresi quelli implementati per le interfacce implementate da questa classe).

Le mie domande specifiche sono:

  1. Ho ragione nel dire che il modo in cui Java è più simile a C ++ come descritto nel terzo paragrafo.
  2. Non capisco cosa si intende per ereditarietà dell'interfaccia nell'ultimo paragrafo. Nell'ereditarietà dell'interfaccia Java è presente un'interfaccia che si estende da un'altra interfaccia. Ma penso che la parola interfaccia abbia qualche altro significato sovraccarico qui. Qualcuno può fornire un esempio in Java di cosa si intende per ereditarietà dell'interfaccia, in modo da comprenderlo meglio?
posta Geek 04.08.2013 - 10:50
fonte

5 risposte

2
  1. Le classi Java sono simili a C ++ come descritto nel terzo paragrafo. Le interfacce Java sono un concetto diverso.
  2. In Java, una classe specifica implicitamente sia un'interfaccia in senso pratico sia l'implementazione. Al contrario, un'interfaccia Java specifica esplicitamente un'interfaccia in senso GoF e non specifica un'implementazione. In entrambi i casi l'ereditarietà implica l'ereditarietà dell'interfaccia. Solo nel caso dell'ereditarietà delle classi implica l'ereditarietà dell'implementazione.

Per un migliore esempio della distinzione, consiglio vivamente di apprendere quanto basta Ruby per capire come una classe può usare method_missing per il proxy su un oggetto non correlato. Ciò fornisce un esempio molto esplicito di ereditarietà dell'interfaccia senza ereditarietà dell'implementazione. (Bonus, il modello OO di Ruby è lo stesso di Smalltalk pur avendo una sintassi più familiare, che ti dà un vantaggio sul resto del libro.)

    
risposta data 04.08.2013 - 11:17
fonte
1
  1. Sì, le classi Java sono simili alle classi C ++ a questo proposito.
  2. Sì, in questo caso, l'interfaccia in realtà non significa interface costrutti linguistici presenti in Java e C #. In questo caso ha un significato più astratto. Penso che sia possibile equipararlo a metodi e campi pubblici, che possono essere richiamati sull'oggetto.

L'ereditarietà della classe qui significa sottotipizzazione standard, in cui la classe figlio eredita il comportamento del genitore. L'ereditarietà dell'interfaccia è molto più legata al polimorfismo e alle chiamate al metodo virtuale. Significa che la classe del bambino può "accettare e rispondere ai messaggi" che il genitore può accettare e rispondere. L'intero "descrive quando un oggetto può essere usato al posto di un altro" è fondamentalmente una definizione di polimorfismo del sottotipo.

    
risposta data 04.08.2013 - 11:26
fonte
1

@Euforic ha già risposto a entrambe le tue domande. Volevo solo estendere la sua spiegazione con ulteriori chiarimenti.

È possibile eseguire "l'ereditarietà della classe" senza che l'interfaccia venga ereditata completamente . Sono passati più di 5 anni che ho toccato Java, ma, se ricordo bene, i metodi "protetti" diventano "privati" per una classe ereditata al di fuori del pacchetto. Ora, in Java, il membro "protetto" farà parte dell'interfaccia di un oggetto ma il membro "privato" non lo è (tutto ciò a cui è possibile accedere utilizzando un'istanza di classe è parte dell'interfaccia, che nel caso di Java è "pubblico" "e" protetto ", credo). In questo scenario il metodo è ereditato (cioè può essere utilizzato all'interno della sottoclasse in quanto è proprio) ma non è possibile chiamare il metodo su istanza di una sottoclasse. Pertanto, si ottiene l'ereditarietà della classe senza che l'interfaccia venga ereditata.

    
risposta data 30.10.2013 - 12:41
fonte
1

Ho trovato questo commento molto interessante e credo che potrebbe contribuire positivamente alla domanda:

Una volta ho partecipato a una riunione di un gruppo di utenti Java in cui James Gosling (l'inventore di Java) era l'oratore in primo piano. Durante la sessione memorabile di Q & A, qualcuno gli ha chiesto: "Se potessi fare di nuovo Java, cosa cambieresti?" "Vorrei lasciare le lezioni", ha risposto. Dopo che la risata si è spenta, ha spiegato che il vero problema non erano le classi in sé, ma piuttosto l'ereditarietà dell'implementazione (il estende la relazione ). L'ereditarietà dell'interfaccia (la relazione degli attrezzi ) è preferibile. Dovresti evitare l'ereditarietà dell'implementazione quando possibile.

link

    
risposta data 06.05.2018 - 04:18
fonte
-1

Per la tua seconda domanda sull'ereditarietà dell'interfaccia: L'ereditarietà dell'interfaccia è logicamente simile all'ereditarietà delle classi, ma la vera ragione per cui viene fornita è quella di fornire flessibilità. Ad esempio, considerare le interfacce del pacchetto di utilità simultanee in java. Al livello superiore abbiamo l'interfaccia executor che ha il metodo eseguito esposto e un'altra interfaccia chiamata executorService estende l'interfaccia executor. Ora, se non ti interessano le funzionalità fornite da executorService , puoi implementare l'interfaccia executor, altrimenti devi solo implementare l'interfaccia executorService e avrai tutte le funzionalità di genitore interfaccia. Questo design può essere osservato nella maggior parte dei pacchetti java, sia esso Collezione framework o Utilità simultanee .

    
risposta data 05.08.2013 - 04:24
fonte