ebben a cikkben Az én ingyenes Java 8 tanfolyam, fogok beszélni a különbség egy mély és egy sekély példányt. A diákat és a cikket PDF formátumban itt töltheti le.
mi a másolat?
a kezdéshez szeretném kiemelni, hogy mi a Java példánya. Először is különbséget kell tenni egy referencia-másolat és egy objektummásolat között. A referencia-másolat, amint azt a név is jelzi, létrehoz egy objektumra mutató hivatkozási változó másolatát., Ha van egy autó objektumunk, egy myCar változó mutat rá, és készítünk egy referencia példányt, akkor most két myCar változónk lesz, de még mindig egy objektum.
1.példa
egy objektummásolat létrehoz egy példányt az objektumról. Tehát, ha ismét lemásoljuk az autó objektumunkat, létrehoznánk egy példányt az objektumról, valamint egy második referencia változót, amely a másolt objektumra utal.
2. példa
mi az objektum?,
mind a mély másolat, mind a sekély másolat objektummásolatok típusai, de mi valójában egy objektum? Gyakran, amikor egy tárgyról beszélünk, egyetlen egységként beszélünk róla, amelyet nem lehet tovább lebontani, mint egy szerény kávébab. Ez azonban túl egyszerű.
3.példa
mondjuk, hogy van egy személy objektumunk. Személyünk tárgya valójában más tárgyakból áll, amint az A 4.példában látható. Személyünk Névobjektumot és Címobjektumot tartalmaz., A név viszont tartalmaz egy keresztnevet és egy vezetéknév objektumot; a Címobjektum egy utcai objektumból és egy városi objektumból áll. Tehát amikor ebben a cikkben a személyről beszélek, valójában az egész objektumhálózatról beszélek.
példa 4
miért akarnánk másolni ezt a személy objektumot? Ha egy objektumot módosítani vagy áthelyezni akarunk, létrehozunk egy objektummásolatot, amelyet általában klónnak nevezünk, miközben továbbra is megőrizzük az eredeti objektumot. Számos különböző módja van egy objektum másolásának,amelyről egy másik cikkben olvashat., Ebben a cikkben mi lesz kifejezetten egy copy konstruktor létrehozni a másolatokat.
sekély másolat
először beszéljünk a sekély példányról. Egy objektum sekély példánya lemásolja a ” fő ” objektumot, de nem másolja a belső objektumokat. A “belső objektumok” az eredeti objektum és annak másolata között oszlanak meg. Például a mi személyünkben egy második személyt hoznánk létre, de mindkét objektum ugyanazt a nevet és címet viseli.
nézzünk meg egy kódolási példát. Az 5. példában van egy osztály személyünk, amely egy nevet és Címobjektumot tartalmaz., A copy constructor veszi az eredetitszemély objektum, majd másolja a referencia változókat.
5. példa
a sekély példány problémája az, hogy a két objektum nem független. Ha módosítja egy személy névobjektumát, a változás megjelenik a másik személy objektumában.
alkalmazzuk ezt egy példára. Tegyük fel, hogy van egy személy objektum egy referencia változó anya; akkor, teszünk egy példányt anya, ami egy második személy objektum, fiú. Ha később a kódban a fiú megpróbál elmozdulni () a Címobjektum módosításával, az anya vele mozog!,
Person mother = new Person(new Name(…), new Address(…));Person son = new Person(mother);son.moveOut(new Street(…), new City(…));
Példa 6
Ez azért fordul elő, mert az anya-fia tárgyak ugyanaz a Cím, tárgy, mint látható Példában bemutatott 7. Amikor megváltoztatjuk a címet egy objektumban, mindkettőben megváltozik!
7.példa
Deep Copy
a sekély példánytól eltérően a deep copy egy objektum teljesen független példánya. Ha lemásolnánk a személy objektumunkat, lemásolnánk a teljes objektumszerkezetet.,
8.példa
egy személy Címobjektumának változása nem tükröződne a másik objektumban, amint azt a 8. példában látható diagram is mutatja. Ha megnézzük a kódot a 9. példában, láthatjuk, hogy nem csak egy másolási konstruktort használunk személyünk objektumán, hanem a belső objektumokon is másolási konstruktorokat használunk.
példa 9
ezzel a mély másolattal újra kipróbálhatjuk az anya-fia példát a 6. példából. Most a fiú képes sikeresen elköltözni!,
azonban ez nem a történet vége. Ahhoz, hogy valódi mély példányt hozzunk létre, tovább kell másolnunk az összes objektum beágyazott elemét, amíg csak primitív típusok és” Immutables ” marad. Nézzük meg az utcai osztályt, hogy jobban illusztráljuk ezt:
példa 10
az utcai objektum két példányváltozóból áll – String név és int szám. az int szám primitív érték, nem objektum. Ez csak egy egyszerű érték, amelyet nem lehet megosztani, így egy másodpéldányos változó létrehozásával automatikusan létrehozunk egy független példányt., A karakterlánc megváltoztathatatlan. Röviden: a megváltoztathatatlan egy objektum, amelyet egyszer létrehoztak, soha többé nem lehet megváltoztatni. Ezért megoszthatja azt anélkül, hogy mély másolatot kellene készítenie.
következtetés
végezetül szeretnék beszélni néhány kódolási technikáról, amelyeket az anya-fia példánkban használtunk. Csak azért, mert egy mély másolat lehetővé teszi egy objektum belső adatainak, például a Címobjektumnak a megváltoztatását, ez nem jelenti azt, hogy kellene., Ezzel csökkentené a kód minőségét, mivel ez a Személyosztályt törékenyebbé tenné a változásokra – amikor a címosztály megváltozik, (potenciálisan) változtatásokat kell alkalmaznia a Személyosztályra is. Például, ha a címosztály már nem tartalmaz utcai objektumot, meg kell változtatnunk a Moveout() módszert a Személyosztályban a Címosztályra már végrehajtott módosítások tetején.
A cikk 6. példájában csak egy új utcai és Városi objektum használatát választottam, hogy jobban szemléltessem a különbséget egy sekély és egy mély példány között., Ehelyett azt javasoljuk, hogy rendeljen egy új Cím, tárgy helyett, hatékonyan konvertáló, hogy hibrid egy sekély, mély másolás, mint látható, a 10. Példa:
Person mother = new Person(new Name(…), new Address(…));Person son = new Person(mother);son.moveOut(new Address(...));
Példa 11
Az objektum-orientált szempontból ez sérti a beágyazás, ezért kerülendő. A kapszulázás az objektumorientált programozás egyik legfontosabb szempontja. Ebben az esetben megsértettem a kapszulázást azáltal, hogy hozzáfértem a Címobjektum belső adataihoz a Személyosztályunkban., Ez árt a kódunknak, mert most belegabalyodtunk a Személyosztályba a Címosztályba, és ha megváltoztatjuk a Címosztályt, az árthat a Személyosztálynak, ahogy fentebb kifejtettem. Bár nyilvánvalóan össze kell kapcsolnia a különböző osztályokat, hogy kódolási projektje legyen, amikor két osztályt csatlakoztat, elemeznie kell a költségeket és az előnyöket.