Un amestec ( eng. mix in ) este un element al unui limbaj de programare (de obicei o clasă sau un modul) care implementează un comportament clar definit. Folosit pentru a rafina comportamentul altor clase, nu este destinat să creeze autoutilizabil .
În limbajele de programare orientate pe obiecte , este o modalitate de implementare a claselor care este diferită de principiile utilizate pe scară largă care au venit din limbajul de programare Simula . Mecanismul este implementat mai întâi în Flavours. Avantajul mixin-urilor este că prin creșterea reutilizabilității codului programului , această tehnică evită multe dintre problemele moștenirii multiple . Cu toate acestea, această metodă își impune limitările.
În majoritatea limbajelor orientate pe obiecte, începând cu Simula , o clasă este definită de atribute , metode , constructori și destructori ca o singură entitate strâns legată. Definiția clasei este completă. Acest fapt li s-a părut util lui Stroustrup și Ellis, care, pe această bază, nu au implementat mixin-uri în C++ la nivel de limbaj (C++ a fost dezvoltat ca o „extensie C compatibilă către Simula”). .
Într-un limbaj mixin, o clasă este definită doar cu atributele și parametrii asociați cu clasa. Metodele sunt definite în altă parte, ca în Flavours și CLOS și sunt funcții generice. Acestea din urmă sunt implementate pentru diferite tipuri prin programare.
Pe lângă Flavours și CLOS, mixin-urile acceptă următoarele limbi:
Un exemplu în Ruby. Clasa implementează conceptul simplu de vârstă. Valoarea vârstei este stocată în variabila internă „ vârstă ”, care este deschisă pentru scriere și citire. Pentru a putea compara vârstele, clasa implementează un singur operator „ <=> ”, iar toate celelalte (mai mare, mai mică, egală etc.) sunt implementate folosind această metodă în modulul de includere „ Comparabil ”.
clasa Vârsta include Comparabil attr_accessor ( : age ) def <=> ( cmp ) @ vârstă <=> cmp . sfarsit de varstaExemplul demonstrează crearea de obiecte și utilizarea metodelor „mixte”:
a , b = Vârsta . nou , Age . nou a . vârsta = 10 b . vârsta = 11 dacă a < b atunci pune „a este mai mic decât b”. SfârşitMixins poate fi văzut ca o implementare incompletă a moștenirii multiple , un anumit tip de ea. În limbile care acceptă moștenirea multiplă, mixin-urile pot fi emulate cu ușurință. De exemplu, în C++ , următorul model poate fi folosit pentru a adăuga un operator „ != ” la o clasă atunci când există un operator „ == ”:
template < typename T > struct AddNoEq { operator bool virtual == ( const T & cmp ) const = 0 ; operator bool != ( const T & cmp ) const { intoarce- te! static_cast < const T *> ( this ) -> operator == ( cmp ); } };Un caz de utilizare simplu pentru clasa de numere complexe :
#include <iostream> struct Complex : public AddNoEq < Complex > { Complex ( int re , int im ) : re_ ( re ), im_ ( im ) { } operator bool virtual == ( const Complex & cmp ) const { return cmp . re_ == this -> re_ && cmp . im_ == this -> im_ ; } // ... privat : int re_ , im_ ; }; int main () { Complex a ( 1 , 2 ), b ( 2 , 3 ); dacă ( a != b ) std :: cout << „Așa ar trebui să fie” << std :: endl ; returnează 0 ; }Această metodă este utilizată într-o formă mai extinsă în biblioteca de operatori Boost .
Funcționalitatea apropiată de impurități este asigurată de interfețele în limbaje precum Java și C# , cu diferența că o interfață specifică doar comportamentul, dar nu oferă o implementare (în Java, începând cu versiunea 1.8, o implementare parțială este permisă într-o interfață , C# introduce conceptul de „implementare implicită” începând cu versiunea 8.0). Mecanismul poate fi util doar pentru reprezentarea polimorfismului . Alte clase care oferă o implementare a unei interfețe sunt utile pentru a aduce funcționalități comune într-un singur loc.
Folosind împreună metode de extensie și interfețe , este posibil să implementați funcționalitatea mixin în C#.