v tomto článku z mého bezplatného kurzu Java 8 budu diskutovat o rozdílu mezi Hlubokou a mělkou kopií. Snímky a článek si můžete stáhnout ve formátu PDF zde.
co je to kopie?
Chcete-li začít, chtěl bych zdůraznit, co je kopie v Javě. Nejprve rozlišujeme mezi referenční kopií a kopií objektu. Referenční kopie, jak název napovídá, vytvoří kopii referenční proměnné směřující k objektu., Pokud máme objekt automobilu, na který ukazuje proměnná myCar a vytvoříme referenční kopii, budeme mít nyní dvě proměnné myCar, ale stále jeden objekt.
Příklad 1
objekt, kopie vytvoří kopii objektu samotného. Pokud bychom tedy znovu zkopírovali náš objekt automobilu, vytvořili bychom kopii samotného objektu a druhou referenční proměnnou odkazující na tento zkopírovaný objekt.
Příklad 2
Co Je Objekt?,
Jak hluboká kopie, tak mělká kopie jsou typy kopií objektů, ale co je vlastně objekt? Často, když mluvíme o objektu, mluvíme o něm jako o jediné jednotce, která nemůže být dále rozdělena, jako skromná kávová zrna. To je však příliš zjednodušené.
příklad 3
Řekněme, že máme objekt osoby. Objekt naší osoby je ve skutečnosti složen z jiných objektů, jak vidíte v příkladu 4. Naše osoba obsahuje objekt jména a objekt adresy., Název zase obsahuje křestní jméno a objekt příjmení; objekt adresy se skládá z pouličního objektu a městského objektu. Takže když mluvím o osobě v tomto článku, vlastně mluvím o celé této síti objektů.
příklad 4
tak proč bychom chtěli kopírovat tento objekt osoby? Kopie objektu, obvykle nazývaná klon, je vytvořena, pokud chceme objekt upravit nebo přesunout a zároveň zachovat původní objekt. Existuje mnoho různých způsobů, jak zkopírovat objekt, o kterém se můžete dozvědět v jiném článku., V tomto článku budeme konkrétně používat Konstruktor kopií k vytvoření našich kopií.
mělká kopie
nejprve promluvme o mělké kopii. Mělká kopie objektu kopíruje „hlavní“ objekt, ale nekopíruje vnitřní objekty. „Vnitřní objekty“ jsou sdíleny mezi původním objektem a jeho kopií. Například v našem osobním objektu bychom vytvořili druhou osobu, ale oba objekty by sdílely stejný název a adresní objekty.
podívejme se na příklad kódování. V příkladu 5 máme naši třídní osobu, která obsahuje objekt jména a adresy., Konstruktor kopií vezme originálosobní objekt a kopíruje jeho referenční proměnné.
Příklad 5
problém s mělké kopie je, že dva objekty nejsou nezávislé. Pokud změníte název objektu jedné osoby, změna se projeví v objektu jiné osoby.
použijeme to na příklad. Řekněme, že máme objekt osoby s referenční proměnnou matkou; pak vytvoříme kopii matky a vytvoříme objekt druhé osoby, syna. Pokud se později v kódu syn pokusí přestěhovat () úpravou svého adresního objektu, matka se s ním pohybuje!,
Person mother = new Person(new Name(…), new Address(…));Person son = new Person(mother);son.moveOut(new Street(…), new City(…));
Příklad 6
k tomu dochází, protože naše matka a syn objekty sdílejí stejnou Adresu objektu,, jak můžete vidět znázorněno v Příkladu 7. Když změníme adresu v jednom objektu, změní se v obou!
Příklad 7
Hluboké Kopírování
na Rozdíl od mělké kopie, hluboké kopie je plně nezávislé kopie objektu. Pokud bychom zkopírovali objekt naší osoby, zkopírovali bychom celou strukturu objektu.,
Příklad 8.
změna Adresy objektu jednoho Člověka by to nemělo být zohledněny v další objekt, jak můžete vidět na obrázku v Příkladu 8. Pokud se podíváme na kód v příkladu 9, můžete vidět, že nejsme jen pomocí kopie konstruktoru na naši Osobu objektu, ale jsme také s využitím kopírování konstruktérů na vnitřní objekty stejně.
příklad 9
pomocí této hluboké kopie můžeme opakovat příklad matka-syn z příkladu 6. Nyní se syn může úspěšně odstěhovat!,
to však není konec příběhu. Chcete-li vytvořit skutečnou hlubokou kopii, musíme kopírovat všechny vnořené prvky objektu osoby, dokud nezůstanou pouze primitivní typy a „neměnné“. Pojďme se podívat na Ulici třída pro lepší ilustraci toto:
Příklad 10
Ulici, objekt se skládá ze dvou proměnných instance – String name a int číslo. int číslo je primitivní hodnota a ne objekt. Je to jen jednoduchá hodnota, kterou nelze sdílet, takže vytvořením proměnné druhé instance automaticky vytváříme nezávislou kopii., Řetězec je neměnný. Stručně řečeno, neměnný je objekt, který, jakmile je vytvořen, nemůže být nikdy znovu změněn. Proto jej můžete sdílet, aniž byste museli vytvářet jeho hlubokou kopii.
závěr
Na závěr bych chtěl mluvit o některých kódovacích technikách, které jsme použili v našem příkladu matka-syn. Jen proto, že hluboká kopie vám umožní změnit vnitřní detaily objektu, jako je objekt adresy, neznamená to, že byste měli., Přitom by snížilo kvalitu kódu, jako by to udělal Člověk, třída křehčí změn – kdykoliv na Adrese třída se změní, budete muset (potenciálně) použít změny na Osobu, třídu také. Například, pokud je Adresa třídy již obsahuje Street objekt, museli bychom změnit moveOut() metoda v Osobě třídě na vrcholu změny, které jsme již na Adresu třídy.
v příkladu 6 tohoto článku jsem se rozhodl použít pouze nový objekt ulice a města, abych lépe ilustroval rozdíl mezi mělkou a hlubokou kopií., Místo toho bych doporučil přiřadit novou Adresu objektu, místo toho, efektivně přeměnit na hybridní mělké a hluboké kopírování, jak můžete vidět v Příkladu 10:
Person mother = new Person(new Name(…), new Address(…));Person son = new Person(mother);son.moveOut(new Address(...));
Příklad 11
V objektově orientované pojmy, to porušuje zapouzdření, a proto je třeba se vyhnout. Zapouzdření je jedním z nejdůležitějších aspektů objektově orientovaného programování. V tomto případě jsem porušil zapouzdření přístupem k interním detailům adresního objektu v naší třídě osob., To poškozuje náš kód, protože jsme nyní zapleteni Osoba, třída Adresy třída a budeme-li provést změny na Adresu, třídu, mohlo by to poškodit Osobu, třídu, jak jsem vysvětlil výše. I když samozřejmě potřebujete propojit své různé třídy, abyste měli kódovací projekt, kdykoli připojíte dvě třídy, musíte analyzovat náklady a přínosy.