Programovanie

Dedenie v Jave, časť 2: Objekt a jeho metódy

Java poskytuje štandardnú knižnicu tried pozostávajúcu z tisícov tried a ďalších referenčných typov. Napriek rozdielom v ich schopnostiach tvoria tieto typy jednu obrovskú hierarchiu dedičstva priamym alebo nepriamym rozšírením Objekt trieda. To platí aj pre všetky triedy a ďalšie referenčné typy, ktoré vytvoríte.

Prvá polovica tohto tutoriálu o dedení v jazyku Java vám ukázala základy dedenia, konkrétne ako používať jazyk Javapredlžuje a Super kľúčové slová na odvodenie podradenej triedy z nadradenej triedy, vyvolanie konštruktorov a metód nadradenej triedy, prepísanie metód a ďalšie. Teraz sa zameriame na materskú loď hierarchie dedičnosti triedy Java, java.lang.Objekt.

Študovať Objekt a jeho metódy vám pomôžu získať funkčnejšie porozumenie dedičnosti a toho, ako to funguje vo vašich programoch Java. Ak sa oboznámite s týmito metódami, pomôže vám to vo väčšom porozumení programom Java.

stiahnuť Získajte kód Stiahnite si zdrojový kód napríklad pre aplikácie v tejto príručke. Vytvoril Jeff Friesen pre JavaWorld.

Objekt: Nadtrieda Java

Objekt je koreňová trieda alebo najvyššia nadtrieda všetkých ostatných tried Java. Uložené v java.lang balíček, Objekt deklaruje nasledujúce metódy, ktoré dedia všetky ostatné triedy:

  • klon chráneného objektu ()
  • boolean equals (Object obj)
  • chránená prázdnota finalize ()
  • Trieda getClass ()
  • int hashCode ()
  • void notify ()
  • void notifyAll ()
  • String toString ()
  • neplatné čakanie ()
  • neplatné čakanie (dlhý časový limit)
  • void wait (long timeout, int nanos)

Trieda Java dedí tieto metódy a môže prepísať každú metódu, ktorá nie je deklarovaná konečné. Napríkladkonečnénatiahnuť() metóda môže byť prepísaná, zatiaľ čo konečnépočkaj () metódy nemôžu.

Pozrime sa na každú z týchto metód a na to, ako vám umožňujú vykonávať špeciálne úlohy v kontexte vašich tried Java. Najskôr zvážme základné pravidlá a mechanizmy Objekt dedenie.

Generické typy

Vo vyššie uvedenom zozname ste si mohli všimnúť getClass (), ktorého Trieda návratový typ je príkladom a generický typ. Všeobecným typom sa budem venovať v budúcom článku.

Rozširujúci objekt: Príklad

Trieda sa môže výslovne rozšíriť Objekt, ako je uvedené v zozname 1.

Výpis 1. Explicitne rozširujúci objekt

public class Zamestnanec rozširuje Object {private String name; public Employee (String name) {this.name = name; } public String getName () {návratové meno; } public static void main (String [] args) {Employee emp = new Employee ("John Doe"); System.out.println (emp.getName ()); }}

Pretože môžete rozšíriť najviac jednu ďalšiu triedu (z časti 1 si uvedomte, že Java nepodporuje viacnásobné dedičstvo založené na triedach), nie ste nútení výslovne rozširovať Objekt; inak by si nemohol rozšíriť inú triedu. Preto by ste predĺžili Objekt implicitne, ako je uvedené v zozname 2.

Výpis 2. Implicitné rozšírenie objektu

public class Employee {private String name; public Employee (String name) {this.name = name; } public String getName () {návratové meno; } public static void main (String [] args) {Employee emp = new Employee ("John Doe"); System.out.println (emp.getName ()); }}

Zostavte zoznam 1 alebo 2 takto:

javac Employee.java

Spustite výslednú aplikáciu:

java zamestnanec

Mali by ste dodržiavať nasledujúci výstup:

John Doe

Zistite o triede: getClass ()

The getClass () metóda vráti runtime triedu ľubovoľného objektu, na ktorý je volaná. The runtime trieda je reprezentovaný a Trieda objekt, ktorý sa nachádza v java.lang balíček. Trieda je vstupným bodom do rozhrania Java Reflection API, o ktorom sa dozviete, keď sa dostaneme k pokročilejším témam programovania v jazyku Java. Zatiaľ vedzte, že sa používa aplikácia Java Trieda a zvyšok Java Reflection API, aby sa dozvedeli o svojej vlastnej štruktúre.

Objekty triedy a statické synchronizované metódy

Vrátený Trieda objekt je objekt, ktorý je uzamknutý pomocou statické synchronizované metódy predstavovanej triedy; napríklad, statická synchronizovaná void foo () {}. (Synchronizáciu Java predstavím v budúcom tutoriáli.)

Duplikovanie objektov: klon ()

The klon () metóda vytvorí a vráti kópiu objektu, na ktorý sa volá. Pretože klon ()návratový typ je Objekt, odkaz na objekt klon () návraty musia byť vrhnuté na skutočný typ objektu pred priradením tohto odkazu k premennej typu objektu. Zoznam 3 predstavuje aplikáciu, ktorá demonštruje klonovanie.

Zoznam 3. Klonovanie objektu

trieda CloneDemo implementuje Cloneable {int x; public static void main (String [] args) hodí CloneNotSupportedException {CloneDemo cd = new CloneDemo (); cd.x = 5; System.out.println ("cd.x =" + cd.x); CloneDemo cd2 = (CloneDemo) cd.clone (); System.out.println ("cd2.x =" + cd2.x); }}

Zoznam 3 CloneDemo trieda implementuje Cloneable rozhranie, ktoré sa nachádza v java.lang balíček. Cloneable je implementovaná triedou (prostredníctvom náradie kľúčové slovo) zabrániť Objektje klon () metóda z hádzania inštancie CloneNotSupportedException trieda (tiež sa nachádza v java.lang).

CloneDemo vyhlasuje za slobodného int- pomenované pole inštancie X a a hlavný() metóda, ktorá túto hodinu precvičuje. hlavný() sa deklaruje s hodí klauzula, ktorá prechádza CloneNotSupportedException do zásobníka metódových volaní.

hlavný() prvé inštancie CloneDemo a inicializuje kópiu výslednej inštancie X do 5. Potom vydá výstupy inštancie X hodnotu a hovory klon () v tomto prípade casting vráteného objektu na CloneDemo pred uložením jeho referencie. Nakoniec vydá klon X hodnota poľa.

Zostaviť zoznam 3 (javac CloneDemo.java) a spustite aplikáciu (java CloneDemo). Mali by ste dodržiavať nasledujúci výstup:

cd.x = 5 cd2.x = 5

Prepísajúci klon ()

Predchádzajúci príklad nebolo potrebné prepísať klon () pretože kód, ktorý volá klon () sa nachádza v klonovanej triede (CloneDemo). Ak je volanie na klon () boli umiestnené v inej triede, musíte ich však prepísať klon (). Pretože klon () je vyhlásený chránené, dostali by ste „klon má chránený prístup v objekte"správa, ak ste ju neprepísali pred zostavením triedy. Výpis 4 predstavuje upravený Výpis 3, ktorý demonštruje prepísanie klon ().

Výpis 4. Klonovanie objektu z inej triedy

trieda Dátové implementácie Cloneable {int x; @Override public Object clone () hodí CloneNotSupportedException {return super.clone (); }} trieda CloneDemo {public static void main (String [] args) hodí CloneNotSupportedException {Data data = new Data (); data.x = 5; System.out.println ("data.x =" + data.x); Data data2 = (Data) data.clone (); System.out.println ("data2.x =" + data2.x); }}

Výpis 4 deklaruje a Údaje triedy, ktorej inštancie sa majú klonovať. Údaje realizuje Cloneable rozhranie, aby sa zabránilo a CloneNotSupportedException pred vyhodením, keď klon () metóda sa volá. Potom vyhlási int- inštančné pole Xa prepíše klon () metóda. The klon () metóda sa vykoná super.clone () volať svoju nadtriedu (tj. Objektje) klon () metóda. Naliehavé klon () metóda identifikuje CloneNotSupportedException v jeho hodí doložka.

Zoznam 4 tiež deklaruje a CloneDemo trieda, ktorá: inštancuje Údaje, inicializuje svoje inštančné pole, odošle hodnotu poľa inštancie, klonuje Údaje objekt a na výstup vydá hodnotu poľa inštancie.

Zostaviť zoznam 4 (javac CloneDemo.java) a spustite aplikáciu (java CloneDemo). Mali by ste dodržiavať nasledujúci výstup:

data.x = 5 data2.x = 5

Plytké klonovanie

Plytké klonovanie (taktiež známy ako plytké kopírovanie) odkazuje na duplikovanie polí objektu bez duplikovania akýchkoľvek objektov, na ktoré sa odkazuje z referenčných polí tohto objektu (ak existujú nejaké referenčné polia). Zoznamy 3 a 4 skutočne demonštrovali povrchné klonovanie. Každá z cd-, cd2-, údaje- a data2-referencované polia identifikujú objekt, ktorý má svoju vlastnú kópiu int- na základe X lúka.

Plytké klonovanie funguje dobre, keď sú všetky polia primitívneho typu a (v mnohých prípadoch), keď sa na ne odkazuje nejaké referenčné pole nemenný (nemeniteľné) predmety. Ak sú však niektoré odkazované objekty zmeniteľné, pôvodný objekt a jeho klon (y) môžu vidieť zmeny vykonané v ktoromkoľvek z týchto objektov. Zoznam 5 ukazuje.

Zoznam 5. Problém s plytkým klonovaním v kontexte referenčného poľa

trieda Zamestnanec implementuje Cloneable {private String name; súkromný int vek; adresa súkromnej adresy; Zamestnanec (meno reťazca, vek, adresa) {this.name = meno; this.age = vek; this.address = adresa; } @Override public Object clone () hodí CloneNotSupportedException {return super.clone (); } Adresa getAddress () {spiatočná adresa; } Reťazec getName () {návratové meno; } int getAge () {návratový vek; }} trieda Adresa {private String city; Adresa (reťazec mesto) {this.city = city; } String getCity () {return city; } void setCity (String city) {this.city = city; }} class CloneDemo {public static void main (String [] args) throws CloneNotSupportedException {Employee e = new Employee ("John Doe", 49, new Address ("Denver")); System.out.println (e.getName () + ":" + e.getAge () + ":" + e.getAddress (). GetCity ()); Zamestnanec e2 = (zamestnanec) e.clone (); System.out.println (e2.getName () + ":" + e2.getAge () + ":" + e2.getAddress (). GetCity ()); e.getAddress (). setCity ("Chicago"); System.out.println (e.getName () + ":" + e.getAge () + ":" + e.getAddress (). GetCity ()); System.out.println (e2.getName () + ":" + e2.getAge () + ":" + e2.getAddress (). GetCity ()); }}

Zoznam 5 darčekov Zamestnanec, Adresaa CloneDemo triedy. Zamestnanec vyhlasuje názov, Veka adresa polia; a je klonovateľný. Adresa vyhlasuje, že adresa pozostávajúca z mesta a jeho inštancií je premenlivá. CloneDemo riadi aplikáciu.

CloneDemoje hlavný() metóda vytvára Zamestnanec objekt a klonuje tento objekt. Potom sa zmení pôvodný názov mesta Zamestnanec objektu adresa lúka. Pretože oboje Zamestnanec objekty odkazujú rovnako Adresa objekt, zmenené mesto vidia oba objekty.

Zostaviť zoznam 5 (javac CloneDemo.java) a spustite túto aplikáciu (java CloneDemo). Mali by ste dodržiavať nasledujúci výstup:

John Doe: 49: Denver John Doe: 49: Denver John Doe: 49: Chicago John Doe: 49: Chicago

Hlboké klonovanie

Hlboké klonovanie (taktiež známy ako hlboké kopírovanie) odkazuje na duplikovanie polí objektu tak, aby boli duplikované všetky odkazované objekty. Ďalej sa odkazované objekty odkazovaných objektov duplikujú atď. Zoznam 6 refaktorov Zoznam 5 na demonštráciu hlbokého klonovania.

Zoznam 6. Hlboké klonovanie poľa adresy

trieda Zamestnanec implementuje Cloneable {private String name; súkromný int vek; adresa súkromnej adresy; Zamestnanec (meno reťazca, vek, adresa) {this.name = meno; this.age = vek; this.address = adresa; } @Override public Object clone () hodí CloneNotSupportedException {Employee e = (Employee) super.clone (); e.adresa = (Adresa) address.clone (); návrat e; } Adresa getAddress () {spiatočná adresa; } Reťazec getName () {návratové meno; } int getAge () {návratový vek; }} trieda Adresa {private String city; Adresa (reťazec mesto) {this.city = city; } @Override public Object clone () {return new Address (new String (city)); } String getCity () {return city; } void setCity (String city) {this.city = city; }} class CloneDemo {public static void main (String [] args) throws CloneNotSupportedException {Employee e = new Employee ("John Doe", 49, new Address ("Denver")); System.out.println (e.getName () + ":" + e.getAge () + ":" + e.getAddress (). GetCity ()); Zamestnanec e2 = (zamestnanec) e.clone (); System.out.println (e2.getName () + ":" + e2.getAge () + ":" + e2.getAddress (). GetCity ()); e.getAddress (). setCity ("Chicago"); System.out.println (e.getName () + ":" + e.getAge () + ":" + e.getAddress (). GetCity ()); System.out.println (e2.getName () + ":" + e2.getAge () + ":" + e2.getAddress (). GetCity ()); }}

Výpis 6 to ukazuje Zamestnanecje klon () metóda najskôr zavolá super.clone (), ktorý povrchne kopíruje názov, Veka adresa polia. Potom zavolá klon () na adresa pole na vytvorenie duplikátu referencovaného Adresa objekt. Adresa prepíše klon () metóda a odhaľuje niekoľko rozdielov od predchádzajúcich tried, ktoré túto metódu prepisujú:

  • Adresa nerealizuje Cloneable. Nie je to potrebné, pretože iba Objektje klon () metóda vyžaduje, aby trieda implementovala toto rozhranie a toto klon () metóda sa nevolá.
  • Naliehavé klon () metóda nehádže CloneNotSupportedException. Táto výnimka je vyvolaná iba z Objektje klon () metóda, ktorá sa nevolá. Výnimka preto nemusí byť spracovaná alebo odovzdaná do zásobníka volaní metód cez klauzulu throws.
  • Objektje klon () metóda sa nevolá (nie je super.clone () volanie), pretože plynulé kopírovanie sa nevyžaduje pre Adresa trieda - existuje iba jedno pole na kopírovanie.
$config[zx-auto] not found$config[zx-overlay] not found