Perché "ListE" è un'interfaccia ma non una "classe astratta"?

3

Nel definire la gerarchia, in primo luogo , si può pensare di incorporare il metodo astratto (comportamento) in abstract class solo perché la classe derivata concreta possiede quel comportamento come comportamento di base con la sua specifica implementazione, < strong> in secondo luogo , si può pensare di incorporare il metodo astratto (comportamento) in interface solo perché la classe concreta derivata possiede quel comportamento come comportamento non-core (periferico) con la sua implementazione specifica.

Poiché non fare affidamento su questo esempio che supporta il punto precedente, di seguito sono riportati i due riferimenti, su cui fare affidamento .

1) Primo riferimento che supporta questo punto:

Interfaces are ideal for defining mixins. Loosely speaking, a mixin is a type that a class can implement in addition to its "primary type" to declare that it provides some optional behavior. For example, Comparable is a mixing interface that allows a class to declare that its instances are ordered with respect to other mutually comparable objects. Such an interface is called a mixin because it allows the optional functionality to be "mixed in" to the type's primary functionality. Abstract classes can't be sued to define mixins for the same reason that they can't be retrofitted onto existing classes: a class cannot have more than one parent, and there is no reasonable place in the class hierarchy to insert a mixin.

2) Secondo riferimento che supporta questo punto :

Nello schizzo UML, la relazione tra interface model e concrete class model è denominata Realisation , dove as, la relazione tra abstract class model e concrete class model è denominata is-a relation. Qui può essere detto is-a , quando class concreto ha un comportamento di base diverso dalla relazione realisation .

Quindi, con questi due riferimenti, sembra list<E> e Collection<E> sono abstract class ma non interface .

Con questa spiegazione sopra, mi piacerebbe capire,

Perché Collection<E> e List<E> è progettato per essere interface in java.util pacchetto?

La mia comprensione è corretta?

    
posta overexchange 13.11.2014 - 19:26
fonte

4 risposte

13

L'implementazione di queste astrazioni come interfacce consente una maggiore flessibilità.

Le interfacce consentono ai programmatori di utilizzare l'ereditarietà multipla del tipo in Java. In questo modo puoi trattare qualsiasi classe come un'istanza dell'interfaccia indipendentemente dalla sua gerarchia di ereditarietà.

Puoi implementare qualsiasi numero di interfacce in una singola classe ma puoi avere solo una singola superclasse (espressa dalla parola chiave extends ).

Allo stesso tempo, nulla ti impedisce di fornire un'implementazione scheletrica di un dato interface . Scrivi un abstract class di implementazione e usalo come preferisci. Hai ancora un posto in cui inserire le parti comuni e non fai dipendere i client della tua API da alcuna implementazione effettiva.

Inoltre, le liste possono avere implementazioni molto diverse e i dettagli dei comportamenti di base possono basarsi su meccanismi che non sono affatto simili.

Dai un'occhiata a LinkedList e ArrayList ad esempio.

Il primo è supportato da un numero di oggetti interconnessi. Quest'ultimo memorizza i suoi elementi in un array. Il modo in cui accedi agli elementi di queste strutture dati è semplicemente diverso. L'effetto di queste operazioni è identico (e comprensibilmente, entrambe queste collezioni implementano l'interfaccia List ) ma il comportamento effettivo, gli algoritmi utilizzati per eseguire quelle operazioni non sono molto comuni.

Per coincidenza, queste classi concrete hanno anche superclassi abstract che fungono da implementazioni scheletriche. LinkedList è un'istanza di List e AbstractSequentialList mentre ArrayList è un List e un AbstractList

List è un'interfaccia a causa di quanto è generale. Non presuppone nulla sull'implementazione. AbstractSequentialList e AbstractList d'altra parte assumono determinati modi di accesso agli elementi. Quindi sono implementati come classi astratte.

In risposta all'inizio della tua domanda

While defining the hierarchy, one can think to embed the abstract method(behaviour) in abstract class only because the derive concrete class posses that as core behaviour with it's specific implementation, one can think to embed the abstract method(behaviour) in interface only because derived concrete class does not posses that as core behaviour(but as peripheral) having it's specific implementation.

Above definition can be understood well with this example

One of the good reference also supports this point:

Joshua Bloch - Effective Java

È vero che l'implementazione di più interfacce in una singola classe consente di combinare insiemi di comportamenti possibilmente non correlati, o come lo si esprime, comportamento periferico ma questo è solo un caso d'uso piuttosto che lo scopo di interfacce nella sua interezza.

L'uso di interfacce per creare mixin è un ottimo caso per loro e l'unico modo per avere ereditarietà multiple in Java, ma sei libero di usare interfacce al di fuori di questo contesto.

È perfettamente valido utilizzare un'interfaccia per definire un insieme di comportamenti principali per una famiglia di classi. In questo caso, non direi che è usato come mixin. Definisce semplicemente un contratto. Allo stesso tempo, può essere usato come mixin da qualsiasi altra classe se il programmatore lo desidera. Si tratta di denominazione e contesto in cui si utilizzano questi concetti.

La distinzione tra il comportamento core e periferico è completamente separata dalla distinzione tra classi e interfacce. Ciò che veramente fa la differenza qui è che l'insieme delle interfacce implementate specifica cosa puoi fare con un oggetto mentre le classi (astratte o meno) nella sua gerarchia ereditaria definiscono come queste le cose vanno fatte.

Una classe astratta con tutti i suoi metodi dichiarati come astratti è proprio come un'interfaccia mal implementata con il suo utilizzo severamente limitata dalla mancanza di capacità riguardo l'ereditarietà multipla del tipo.

    
risposta data 13.11.2014 - 19:48
fonte
5

Quindi un'interfaccia implica un contratto. Garantisci che qualsiasi classe che implementa l'interfaccia contenga questi metodi, con questi tipi di parametri, e restituisca questo tipo. Questo è fantastico quando sai che ci sono molti modi diversi di fare la stessa cosa (mantenere elenchi, ordinamento, ecc.)

Una classe astratta, d'altra parte, dice che ci sono diversi modi di implementare questa cosa, ma condivideranno tutti un insieme di funzionalità e fornirò tale funzionalità in questa classe. Questo è dove i due divergono. Uno dice che hai qualche conoscenza che ti permette di sapere che TUTTE le implementazioni faranno una parte nello stesso modo. Questo può essere applicato in molti casi, ma per cose come elenchi o ordinamenti, ci sarà quasi sempre un nuovo modo nuovo di fare cose che non hai ancora pensato. Ecco perché usi un'interfaccia e non una classe astratta.

    
risposta data 13.11.2014 - 19:45
fonte
2

Stai citando il tuo riferimento (Joshua Bloch, Effective Java) fuori dal contesto. Non sta affermando uno scopo particolare per le interfacce e che dovrebbero essere utilizzate solo a tale scopo. Sta elencando una lista (non esaustiva) di possibili applicazioni per loro, tutte rientranti nell'intestazione generale "Preferisci le interfacce alle classi astratte". Come si ottiene da questo per decidere che List<> sarebbe in qualche modo migliore di una classe astratta, non ne sono sicuro, ma sembra che tu stia raccogliendo dettagli sull'argomento di Bloch senza comprenderne lo scopo generale.

    
risposta data 14.11.2014 - 14:33
fonte
0

I tipi di raccolta che utilizzano interface anziché abstract class sono un errore. In effetti, un errore così grave che il linguaggio Java SE 8 ha avuto estensioni bizzarre si innestò su di esso in modo che le interfacce potessero avere metodi di implementazione.

Quindi, perché l'errore? Idealmente, si desidera definire un'interfaccia (definizione generale di "interfaccia", non la parola chiave Java) senza dipendere dall'implementazione. Il framework delle collezioni Java 2 è stato sviluppato con l'assunzione presumibilmente arrogante che tutti i metodi che avresti mai desiderato per il tipo potrebbero essere determinati in anticipo. Questo atteggiamento ha portato gli hack a supportare le raccolte in quasi tutte le principali revisioni di Java.

C'è lo strano vantaggio di List di essere un interface . AbstractCollection viene utilizzato per l'implementazione comune di List e Set ma non si vorrebbe che sottotipi quelli. Anche se, il più delle volte, tale sottotitolo è inappropriato.

    
risposta data 16.11.2014 - 15:48
fonte

Leggi altre domande sui tag