aproape toate limbajele de programare orientate pe obiecte oferă o modalitate de a copia obiecte. Deoarece majoritatea limbilor nu oferă majoritatea obiectelor pentru Programe, un programator trebuie să definească modul în care un obiect trebuie copiat, la fel cum trebuie să definească dacă două obiecte sunt identice sau chiar comparabile în primul rând. Multe limbi oferă un anumit comportament implicit.modul în care se rezolvă copierea variază de la o limbă la alta și ce concept de obiect are.o copie leneșă este o implementare a unei copii profunde., La copierea inițială a unui obiect, se utilizează o copie (rapidă) superficială. Un contor este, de asemenea, utilizat pentru a urmări câte obiecte împărtășesc datele. Când programul dorește să modifice un obiect, poate determina dacă datele sunt partajate (examinând contorul) și poate face o copie profundă, dacă este necesar.
Lazy copy arată spre exterior la fel ca o copie profundă, dar profită de viteza unei copii superficiale ori de câte ori este posibil. Dezavantajul este costurile de bază destul de ridicate, dar constante din cauza contorului. De asemenea, în anumite situații, referințele circulare pot cauza probleme.
copia leneșă este legată de copy-on-write.,
În JavaEdit
următor prezintă exemple pentru unul dintre cele mai utilizate limbaje orientate obiect, Java, care ar trebui să acopere aproape orice mod ca un limbaj orientat-obiect poate trata această problemă.spre deosebire de C++, obiectele din Java sunt întotdeauna accesate indirect prin referințe. Obiectele nu sunt niciodată create implicit, ci sunt întotdeauna trecute sau atribuite de o variabilă de referință. (Metodele din Java sunt întotdeauna trecute prin valoare, cu toate acestea, este valoarea variabilei de referință care este trecută.,) Mașina virtuală Java gestionează colectarea gunoiului, astfel încât obiectele să fie curățate după ce nu mai sunt accesibile. Nu există nici o modalitate automată de a copia orice obiect dat în Java.
copierea este de obicei efectuată printr-o metodă clonă() a unei clase. Această metodă, de obicei, la rândul său, apelează metoda clone() a clasei sale părinte pentru a obține o copie și apoi face orice proceduri de copiere personalizate., În cele din urmă, aceasta ajunge la metoda clone() a Object
(clasa cea mai de sus), care creează o nouă instanță din aceeași clasă ca obiectul și copiază toate câmpurile în noua instanță (o „copie superficială”). Dacă se utilizează această metodă, clasa trebuie să pună în aplicare Cloneable
interfață marker, sau altfel se va arunca o CloneNotSupportedException. După obținerea unei copii de la clasa părinte, o clasă ‘ clone proprii() metoda poate oferi apoi capacitatea de clonare personalizate, cum ar fi copierea profundă (adică., duplicați unele dintre structurile menționate de obiect) sau dați noii instanțe un nou ID unic.
tipul de retur al clonei () este Object
, dar implementatorii unei metode de clonare ar putea scrie tipul obiectului clonat în schimb datorită suportului Java pentru tipurile de retur covariante. Un avantaj al utilizării clone () este că, deoarece este o metodă suprascrisă, putem apela clone () pe orice obiect și va folosi metoda clone () a clasei sale, fără ca codul de apel să fie necesar să știe ce este acea clasă (care ar fi necesară cu un constructor de copii).,
un dezavantaj este că de multe ori nu se poate accesa metoda clone() pe un tip abstract. Cele mai multe interfețe și clase abstracte în Java nu specifică o clonă publică() metodă. Astfel, de multe ori singura modalitate de a utiliza metoda clone() este dacă clasa unui obiect este cunoscută, ceea ce este contrar principiului abstractizării utilizării celui mai generic Tip posibil. De exemplu, dacă cineva are o referință listă în Java, nu se poate invoca clone () pe acea referință, deoarece lista specifică nici o clonă publică () metodă., Implementări de listă ca ArrayList și LinkedList toate au, în general, clone() metode, dar este abstractizare incomod și rău pentru a transporta în jurul valorii de tipul de clasă a unui obiect.un alt mod de a copia obiecte în Java este de a le serializa prin interfața Serializable
. Acest lucru este de obicei folosit în scopuri de persistență și protocol de sârmă, dar creează copii ale obiectelor și, spre deosebire de clonă, o copie profundă care se ocupă cu grație grafice ciclate de obiecte este ușor disponibilă cu un efort minim de la un programator.,ambele metode suferă de o problemă notabilă: constructorul nu este utilizat pentru obiecte copiate cu clonă sau serializare. Acest lucru poate duce la erori cu date inițializate necorespunzător, împiedică utilizarea câmpurilor de membru final
și face întreținerea dificilă. Unele utilități încearcă să depășească aceste probleme folosind reflecția pentru a copia obiecte profunde, cum ar fi biblioteca de clonare profundă.,
în eiffeledit
obiectele Runtime din Eiffel sunt accesibile fie indirect prin referințe, fie ca obiecte extinse care sunt încorporate în obiectele care le folosesc. Adică câmpurile unui obiect sunt stocate fie extern, fie intern.
clasa Eiffel ANY
conține caracteristici pentru copierea superficială și profundă și clonarea obiectelor. Toate clasele Eiffel moștenesc de la ANY
, astfel încât aceste caracteristici sunt disponibile în toate clasele, și sunt aplicabile atât de referință și obiecte extinse.,
caracteristica copy
produce o copie superficială, câmp cu câmp, de la un obiect la altul. În acest caz nu este creat niciun obiect nou. Dacă y
au fost copiate x
, apoi aceleași obiecte referite de y
înainte de aplicarea copy
, va fi, de asemenea, referire către x
dupa copy
caracteristică completeaza.,
Pentru un efect crearea unui nou obiect care este un superficial duplicat al y
, funcția twin
este folosit. În acest caz, un obiect nou este creat cu câmpurile sale identice cu cele ale sursei.
funcția twin
se bazează pe caracteristica copy
, care pot fi redefinite în descendenții ANY
, dacă este necesar. Rezultatul twin
este de tipul ancorat like Current
.,
Adânc copierea și crearea de adânc gemeni se poate face folosind caracteristicile deep_copy
și deep_twin
, din nou, moștenit de la clasa ANY
. Aceste caracteristici au potențialul de a crea multe obiecte noi, deoarece ele duplică toate obiectele dintr-o întreagă structură de obiect. Deoarece noi obiecte duplicat sunt create în loc de a copia pur și simplu referințe la obiecte existente, operațiuni deep va deveni o sursă de probleme de performanță mai ușor decât operațiunile de mică adâncime.,
În alte languagesEdit
În C#, mai degrabă decât folosind interfața ICloneable
, o extensie generic metodă poate fi folosit pentru a crea o copie profundă folosind reflecție. Aceasta are două avantaje: în primul rând, oferă flexibilitatea de a copia fiecare obiect fără a fi nevoie să specificați fiecare proprietate și Variabilă pentru a fi copiate manual. În al doilea rând, deoarece tipul este generic, compilatorul se asigură că obiectul destinație și obiectul sursă au același tip.,
În Objective-C, metodele copy
și mutableCopy
sunt moștenite de toate obiectele și destinate pentru efectuarea de copii; acesta din urmă este de a crea un mutabil tip de obiectul original. Aceste metode său apel copyWithZone
și mutableCopyWithZone
metode, respectiv, pentru a efectua copierea. Un obiect trebuie să implementeze metoda corespunzătoare copyWithZone
pentru a putea fi copiat.
în OCaml, funcția de bibliotecă Oo.copy efectuează copierea superficială a unui obiect.,
în Ruby, toate obiectele moștenesc două metode pentru efectuarea copiilor superficiale, clone și dup. Cele două metode diferă în care clone
copiază un obiect contaminat de stat, stare congelată, și orice singleton metode poate fi, întrucât dup
copii numai sa tentată de stat. Copii profunde pot fi realizate prin dumping și încărcarea unui obiect octet stream sau YAML serializare. Alternativ, puteți utiliza deep_dive gem pentru a face o copie profundă controlată a graficelor dvs. de obiecte.,
În Perl, structurile imbricate sunt stocate prin utilizarea de referințe, astfel un dezvoltator poate fie buclă peste întreaga structură și re-referință datele sau de a folosi funcția dclone()
din modulul Stocabil.
în VBA, o atribuire de variabile de tip Object
este o copie superficială, o atribuire pentru toate celelalte tipuri (tipuri numerice, șir, tipuri definite de utilizator, matrice) este o copie profundă. Deci, cuvinte cheie Set
pentru o misiune semnalează o copie superficială și (opțional) cheie Let
semnale o copie profundă., Nu există o metodă încorporată pentru copii profunde ale obiectelor în VBA.
Lasă un răspuns