Welcome to Our Website

copie superficială vs. profundă în Java

În acest articol din cursul meu gratuit Java 8, voi discuta diferența dintre o copie profundă și o copie superficială. Puteți descărca diapozitivele și articolul în format PDF aici.

ce este o copie?

Pentru început, aș dori să subliniez ce este o copie în Java. Mai întâi, să diferențiem între o copie de referință și o copie obiect. O copie de referință, după cum sugerează și numele, creează o copie a unei variabile de referință care indică un obiect., Dacă avem un obiect Car, cu o variabilă myCar îndreptată spre el și facem o copie de referință, vom avea acum două variabile myCar, dar încă un obiect.

Exemplul 1

Un obiect copia creează o copie a obiectului în sine. Deci, dacă am copiat din nou Obiectul nostru auto, am crea o copie a obiectului în sine, precum și o a doua variabilă de referință care face referire la obiectul copiat.

Exemplul 2

Ce Este un Obiect?,

atât o copie profundă, cât și o copie superficială sunt tipuri de copii de obiecte, dar ce este cu adevărat un obiect? Adesea, când vorbim despre un obiect, vorbim despre el ca o singură unitate care nu poate fi descompusă mai departe, ca o boabe de cafea umilă. Cu toate acestea, acest lucru este suprasimplificat.

Exemplul 3

Spunem că avem o Persoană obiect. Obiectul nostru persoană este de fapt compus din alte obiecte, după cum puteți vedea în exemplul 4. Persoana noastră conține un obiect de nume și un obiect de adresă., Numele, la rândul său, conține un FirstName și un obiect LastName; obiectul de adresă este compus dintr-un obiect de stradă și un obiect de oraș. Deci când vorbesc despre persoană în acest articol, vorbesc de fapt despre întreaga rețea de obiecte.

Exemplul 4

deci, de ce am dori să copiem acest obiect persoană? O copie a obiectului, numită de obicei clonă, este creată dacă dorim să modificăm sau să mutăm un obiect, păstrând în același timp obiectul original. Există multe modalități diferite de a copia un obiect despre care puteți afla într-un alt articol., În acest articol vom folosi în mod special un constructor de copii pentru a crea copiile noastre.

copie superficială

Mai întâi să vorbim despre copia superficială. O copie superficială a unui obiect copiază obiectul „principal”, dar nu copiază obiectele interioare. „Obiectele interioare” sunt împărțite între obiectul original și copia sa. De exemplu, în Obiectul nostru persoană, am crea o a doua persoană, dar ambele obiecte ar avea același nume și obiecte de adresă.

să ne uităm la un exemplu de codificare. În exemplul 5, Avem persoana noastră de clasă, care conține un nume și un obiect de adresă., Constructorul de copiere ia originalulobiectul persoanei și copiază variabilele sale de referință.

exemplul 5

problema cu copia superficială este că cele două obiecte nu sunt independente. Dacă modificați numele obiectului unei persoane, modificarea va fi reflectată în obiectul celeilalte persoane.

să aplicăm acest lucru unui exemplu. Să presupunem că avem un obiect persoană cu o mamă variabilă de referință; apoi, vom face o copie a mamei, creând un obiect a doua persoană, fiul. Dacă mai târziu în cod, fiul încearcă să se muteout () modificând obiectul adresei sale, mama se mișcă cu el!,

Person mother = new Person(new Name(…), new Address(…));Person son = new Person(mother);son.moveOut(new Street(…), new City(…));

Exemplul 6

Acest lucru se întâmplă pentru că mama și fiul nostru obiecte împărtășesc aceeași Adresă obiect, după cum puteți vedea ilustrat în Exemplul 7. Când schimbăm Adresa într-un obiect, se schimbă în ambele!

Exemplul 7

Copie Profundă

spre Deosebire de superficial copie, o copie profundă este un sistem complet independent de copia unui obiect. Dacă am copia Obiectul nostru persoană, am copia întreaga structură a obiectului.,

Exemplul 8

O schimbare de Adresa, obiect de o singură Persoană n-ar fi reflectate în alte obiecte, după cum puteți vedea prin diagrama în Exemplul 8. Dacă aruncăm o privire la codul din exemplul 9, puteți vedea că nu folosim doar un constructor de copiere pe Obiectul nostru persoană, ci folosim și constructori de copiere și pe obiectele interioare.

exemplul 9

folosind această copie profundă, putem încerca din nou exemplul mamă-fiu din exemplul 6. Acum, fiul este capabil să se mute cu succes!,

cu toate acestea, acesta nu este sfârșitul poveștii. Pentru a crea o copie profundă adevărată, trebuie să continuăm să copiem toate elementele imbricate ale obiectului persoanei, până când rămân doar tipuri primitive și „imutabile”. Să ne uităm la Strada de clasă pentru a ilustra mai bine acest lucru:

10

Strada obiect este compus din două variabile de instanta – String nume și int numar. numărul int este o valoare primitivă și nu un obiect. Este doar o valoare simplă care nu poate fi partajată, așa că prin crearea unei variabile de a doua instanță, creăm automat o copie independentă., String este un imuabil. Pe scurt, un imuabil este un obiect, care, odată creat, nu mai poate fi schimbat niciodată. Prin urmare, îl puteți partaja fără a fi nevoie să creați o copie profundă a acestuia.pentru a încheia, aș dori să vorbesc despre câteva tehnici de codificare pe care le-am folosit în exemplul nostru mamă-fiu. Doar pentru că o copie profundă vă va permite să modificați detaliile interne ale unui obiect, cum ar fi obiectul de adresă, nu înseamnă că ar trebui., Acest lucru ar scădea calitatea codului, deoarece ar face clasa persoană mai fragilă la schimbări – ori de câte ori clasa de adresă este schimbată, va trebui să aplicați (potențial) modificări și clasei persoană. De exemplu, dacă clasa de adrese nu mai conține un obiect de stradă, va trebui să schimbăm metoda moveOut() din clasa persoană, pe lângă modificările pe care le-am făcut deja la clasa de adrese.

în exemplul 6 al acestui articol am ales doar să folosesc un obiect nou de stradă și oraș pentru a ilustra mai bine diferența dintre o copie superficială și una profundă., În schimb, mi-ar recomandăm să alocați o Adresă nouă obiect în schimb, în mod eficient de conversie de la un hibrid de un superficială și o copie profundă, după cum puteți vedea în Exemplul 10:

Person mother = new Person(new Name(…), new Address(…));Person son = new Person(mother);son.moveOut(new Address(...));

Exemplu 11

În obiect-orientate termeni, acest lucru încalcă încapsulare, și, prin urmare, ar trebui să fie evitate. Încapsularea este unul dintre cele mai importante aspecte ale programării orientate pe obiecte. În acest caz, am încălcat încapsularea accesând detaliile interne ale obiectului de adresă din clasa noastră de persoane., Acest lucru dăunează codului nostru, deoarece acum am încurcat clasa de persoane în clasa de adrese și dacă facem modificări la clasa de adrese în jos, ar putea dăuna clasei de persoane așa cum am explicat mai sus. În timp ce, evident, trebuie să vă Interconectați diferitele clase pentru a avea un proiect de codificare, ori de câte ori conectați două clase, trebuie să analizați costurile și beneficiile.

Lasă un răspuns

Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *