2009-05-13 10 views

risposta

15

il mix-in è un caso specifico e limitato di ereditarietà (multipla) utilizzato ai fini dell'implementazione; alcune lingue (ad es. Ruby) la supportano senza supportare l'ereditarietà multipla generalizzata.

42

Un mix in viene in genere utilizzato con ereditarietà multipla. Quindi, in questo senso, non c'è "nessuna differenza".

Il dettaglio è che un Mix in è raramente utile come oggetto autonomo.

Ad esempio, supponiamo di avere un nome Mix In "ColorAndDimension", che aggiunge una proprietà di colore, larghezza e altezza.

Ora è possibile aggiungere ColorAndDimension a una, ad esempio, una Shape Class, una Sprite Class, una Car Class, ecc. E avranno tutti la stessa interfaccia (diciamo get/setColor, get/setHeight/Width, ecc.)

Quindi, nel caso generico un'eredità di Mix in IS. Ma puoi obiettare che è una questione del ruolo della classe nel dominio generale se un Mix in è una classe "primaria" o semplicemente un mix.

Modifica - solo per chiarire.

Sì, un mix in può essere considerato, nel gergo moderno di oggi, un'interfaccia con un'implementazione associata. È semplicemente ereditarietà semplice, vecchia, quotidiana, che usa una classe semplice, vecchia, di tutti i giorni. È solo una specifica applicazione di MI. La maggior parte delle lingue non fornisce un Mix in uno stato speciale, è solo una classe che è stata progettata per essere "mixata", piuttosto che usata da sola.

3

"Un mixin è un frammento di una classe nel senso che è destinato a essere composto con altre classi o mixin." -DDJ

Un mixin è un frammento di classe o di codice che non è inteso per l'utilizzo autonomo, ma è invece necessario utilizzarlo all'interno di un'altra classe. Compilandolo come campo membro/variabile o come segmento di codice. Ho più esposizione al dopo. È un po 'meglio del codice standard di copia-incolla.

Here's a great DDJ article that introduces the subject.

Il/SDK "Source" Half-Life 2 è un grande esempio di C++ mixins. In tale ambiente le macro definiscono blocchi di codice considerevoli che possono essere aggiunti per conferire alla classe uno specifico "sapore" o caratteristica.

Guarda l'esempio di wiki di origine: Authoring a Logical Entity. Nel codice di esempio la macro DECLARE_CLASS può essere considerata un mixin. Source SDK utilizza estensivamente i mix per standardizzare il codice di accesso ai dati e attribuire comportamenti alle entità.

0

Con l'ereditarietà multipla, la nuova classe può essere composta da più superclassi. Puoi chiamare solo i metodi definiti in una qualsiasi delle superclassi.

D'altro canto, mixin è una sottoclasse astratta che può essere utilizzata per specializzare il beavior di una varietà di classi padre. I mixer possono chiamare un metodo (ad esempio sayHello(): String) anche se non definiscono tale metodo.

mixin M { 
    name: String 
    defmethod greetings() { print sayHello() + " " + name} 
} 

Come si vede, è possibile chiamare sayHello() anche se non è definito da nessuna parte.Se si aggiunge il mixin M alla classe C, lo C dovrebbe fornire il metodo sayHello().

+1

non sicuro della correttezza della tua prima dichiarazione - le classi possono definire i propri metodi – EugeneMi

15

Qual è la differenza tra mixin ed ereditarietà?

Un mix-in è una classe di base si può ereditare da per fornire funzionalità aggiuntive. Il nome "mix-in" indica che è destinato a essere mescolato con altro codice. In quanto tale, l'inferenza è che non istanziate la classe mix-in da sola. Spesso il mix-in viene utilizzato con altre classi base. Pertanto i mixaggi sono un sottoinsieme, o caso speciale, di ereditarietà.

I vantaggi dell'utilizzo di un mix-in su un'eredità singola sono la possibilità di scrivere il codice per la funzionalità una volta e quindi utilizzare la stessa funzionalità in più classi diverse. Lo svantaggio è che potrebbe essere necessario cercare quella funzionalità in altri luoghi oltre a dove è usata, quindi è bene attenuare lo svantaggio mantenendolo vicino.

Ho trovato personalmente un mix-in necessario per l'utilizzo su un'ereditarietà singola dove stiamo scrivendo un sacco di codice simile, ma i casi di test sono istanziati in base alla loro ereditarietà di un caso base e l'unico modo per mantenere il codice a portata di mano (e nello stesso modulo), senza fare troppi problemi con i numeri di copertura, è quello di ereditare dall'oggetto e fare in modo che i casi figlio ereditino sia dalla base del test-case universale che dalla base personalizzata che si applica solo a loro.

mixin in confronto e il contrasto con le classi astratte Base

sono sia una forma di classe genitore che non è destinato ad essere istanziati.

Un mixin fornisce la funzionalità, ma è in grado di utilizzare direttamente esso. Un utente è destinato a usarlo attraverso una (sotto) classe.

Un classe di base astratta fornisce un'interfaccia, ma senza funzionalità utilizzabile. Un utente è destinato a creare la funzionalità chiamata dall'interfaccia.

In Python, alcune classi nel modulo abc sono esempi di classi padre che forniscono entrambe funzionalità tramite l'ereditarietà e le interfacce astratte che devono essere implementate dalla sottoclasse. Queste idee non si escludono a vicenda.

Sommario

In parole povere, un mix-in è solo una classe di base che non avrebbe istanziare da sola, e in genere utilizzata come classe base secondaria in ereditarietà multipla.

0

penso che la sua importante notare, che mixin non implica eredità. Secondo wikipedia, un Mixin è:

Nei linguaggi di programmazione orientati agli oggetti, un mixin è una classe che contiene metodi per l'uso da altre classi senza dover essere la classe madre di quelle altre classi.Come quelle altre classi ottengono l'accesso ai metodi del mixin dipende dalla lingua. I mixin sono a volte descritti come "inclusi" anziché "ereditati".

In particolare, in un linguaggio come Perl, mixins possono essere aggiunti utilizzando il modulo Exporter:

package Mixins; 

use Exporter qw(import); 
our @EXPORT_OK = qw(pity); 

# assumes it will be mixed-in to a class with a _who_do_i_pity method 
sub pity { 
    my ($self) = @_; 
    printf("I pity %s\n", $self->_who_do_i_pity('da foo')); 
} 

Quale può essere miscelato in qualsiasi modulo contenente uno, o più, il metodo (s) a un tempo:

package MrT 

use Mixins qw(pity); 

sub new { 
    return bless({}, shift); 
} 

sub _who_do_i_pity { 
    return 'da foo!' 
} 

Poi, nel vostro modulo MrT può essere utilizzato nel seguente modo:

use MrT; 

MrT->new()->pity(); 

So che è un esempio assurdo, ma ha il significato di ...

2

Mixin è un concetto astratto e tutto ciò che soddisfa il suo requisito può essere considerato come un mixin.

Ecco una definizione da Wikipedia.

Nei linguaggi di programmazione orientati agli oggetti, un mixin è una classe che contiene metodi per l'utilizzo da parte di altre classi senza dover essere la classe madre di quelle altre classi. Il modo in cui quelle altre classi ottengono l'accesso ai metodi del mixin dipende dalla lingua. Le mistine sono talvolta descritte come "incluse" piuttosto che "ereditate".

In breve, la differenza fondamentale da un'eredità è che i mix-ins non ha bisogno di avere un "is-a" relazione come in eredità.

Dal punto di vista dell'implementazione, è possibile considerarlo un'interfaccia con le implementazioni. Ad esempio, una classe astratta in Java può essere considerata come un mixin se Java supporta l'ereditarietà multipla.

+0

Sto avendo un momento difficile per comprendere la frase in grassetto. Sembra che "la differenza (di B?) Da A è che (B?) Ha bisogno di qualcosa come in A". Stai parlando di differenza o somiglianza? – RayLuo

+0

@RayLuo Whoops ... Ho fatto un errore di battitura. Mi dispiace di confonderti. I mix-in NON devono necessariamente avere una relazione "è-a" – Alex

0

tl; dr

mixin e ereditarietà multipla hanno la stessa forma. Ma hanno semantica diversa: mixin ha le classi base che forniscono l'implementazione della funzione. Per l'ereditarietà, le classi base forniscono un'interfaccia e la sottoclasse ha l'implementazione.

Ma in ogni caso, la composizione è preferibile rispetto mixin IMO