Java ponuja standardno knjižnico razredov, ki jo sestavljajo tisoči razredov in drugih referenčnih vrst. Kljub razlikam v njihovih zmožnostih ti tipi tvorijo eno veliko dediščinsko hierarhijo z neposrednim ali posrednim razširjanjem Predmet
razred. To velja tudi za vse razrede in druge referenčne vrste, ki jih ustvarite.
Prva polovica te vadnice o dedovanju Java vam je pokazala osnove dedovanja, natančneje, kako uporabljati Javopodaljša
in super
ključne besede za pridobivanje podrejenega razreda iz nadrejenega razreda, priklic konstruktorjev in metod nadrejenega razreda, razveljavitev metod in še več. Zdaj se bomo osredotočili na nadrejenost hierarhije dedovanja razreda Java, java.lang.Object
.
Študiranje Predmet
in njegove metode vam bodo pomagale do bolj funkcionalnega razumevanja dedovanja in njegovega delovanja v programih Java. Če boste seznanjeni s temi metodami, boste na splošno lažje razumeli programe Java.
Predmet: Javin superklasa
Predmet
je korenski razred ali končni superrazred vseh drugih razredov Java. Shranjeno v java.lang
paket, Predmet
razglasi naslednje metode, ki jih podedujejo vsi drugi razredi:
klon zaščitenega predmeta ()
logično enako (objekt obj)
zaščitena praznina finalize ()
Razred getClass ()
int hashCode ()
obvestilo o ničnosti ()
void notifyAll ()
String toString ()
neveljavno čakanje ()
neveljavno čakanje (dolga časovna omejitev)
neveljavno čakanje (dolga časovna omejitev, int nanos)
Razred Java podeduje te metode in lahko preglasi katero koli metodo, ki ni deklarirana dokončno
. Na primerdokončno
toString ()
je mogoče preglasiti, medtem ko dokončno
počakaj ()
metode ne morejo.
Ogledali si bomo vsako od teh metod in kako vam omogočajo izvajanje posebnih nalog v okviru predavanj Java. Najprej si oglejmo osnovna pravila in mehanizme za Predmet
dedovanje.
Generične vrste
Na zgornjem seznamu ste morda že opazili getClass ()
, čigar Razred
vrsta return je primer a generični tip. V prihodnjem članku bom razpravljal o generičnih vrstah.
Razširjeni predmet: primer
Razred se lahko izrecno razširi Predmet
, kot je prikazano v seznamu 1.
Seznam 1. Izrecno razširitev predmeta
javni razred Employee razširi Object {private String name; javni zaposleni (ime niza) {this.name = ime; } javni niz getName () {return ime; } public static void main (String [] args) {Employee emp = new Employee ("John Doe"); System.out.println (emp.getName ()); }}
Ker lahko razširite največ en drug razred (spomnite se iz 1. dela, da Java ne podpira večkratnega dedovanja na osnovi razredov), niste prisiljeni izrecno razširiti Predmet
; v nasprotnem primeru ne bi mogli razširiti nobenega drugega razreda. Zato bi podaljšali Predmet
implicitno, kot je prikazano v seznamu 2.
Seznam 2. Implicitno razširjanje predmeta
javni razred Zaposlen {ime zasebnega niza; javni zaposleni (ime niza) {this.name = ime; } javni niz getName () {return ime; } public static void main (String [] args) {Employee emp = new Employee ("John Doe"); System.out.println (emp.getName ()); }}
Sestavite seznam 1 ali seznam 2, kot sledi:
javac zaposleni.java
Zaženite nastalo aplikacijo:
java zaposleni
Upoštevati morate naslednje rezultate:
John Doe
Izvedite več o razredu: getClass ()
The getClass ()
vrne izvajalni razred katerega koli predmeta, na katerem je poklican. The izvajalni razred predstavlja a Razred
predmet, ki ga najdemo v java.lang
paket. Razred
je vstopna točka v Java Reflection API, o katerem boste izvedeli, ko se bomo lotili bolj naprednih tem v programiranju Java. Zaenkrat vedite, da aplikacija Java uporablja Razred
in preostali Java Reflection API za spoznavanje lastne strukture.
Predmeti razredov in statične sinhronizirane metode
Vrnjeni Razred
object je predmet, ki ga je zaklenil statično sinhroniziran
metode zastopanega razreda; na primer, statična sinhronizirana void foo () {}
. (Sinhronizacijo Java bom predstavil v prihodnji vadnici.)
Podvajanje predmetov: clone ()
The klon ()
metoda ustvari in vrne kopijo predmeta, na katerem je poklican. Ker klon ()
vrsta vrnitve je Predmet
, sklic na objekt, ki klon ()
vrnitve je treba oddati dejanskemu tipu predmeta, preden dodelite to referenco spremenljivki vrste predmeta. Seznam 3 predstavlja aplikacijo, ki prikazuje kloniranje.
Seznam 3. Kloniranje predmeta
razred CloneDemo izvaja Cloneable {int x; public static void main (String [] args) vrže 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); }}
Seznam 3 CloneDemo
razred izvaja Klonirano
vmesnik, ki ga najdete v java.lang
paket. Klonirano
izvaja razred (prek izvaja
ključna beseda) za preprečevanje Predmet
je klon ()
od metanja primerka datoteke CloneNotSupportedException
razred (najdemo tudi v java.lang
).
CloneDemo
razglasi en sam int
-imenovano polje primerka x
in a glavni ()
metoda, ki izvaja ta razred. glavni ()
je razglašen z meti
klavzula, ki preide CloneNotSupportedException
navzgor po klicu metode.
glavni ()
prvi primerki CloneDemo
in inicializira nastalo kopijo primerka x
do 5
. Nato izpiše primerke x
vrednost in klici klon ()
v tem primeru vrne vrnjeni predmet v CloneDemo
preden shranite sklic. Končno izpiše klonove x
vrednost polja.
Sestavi seznam 3 (javac CloneDemo.java
) in zaženite aplikacijo (java CloneDemo
). Upoštevati morate naslednje rezultate:
cd.x = 5 cd2.x = 5
Preglasitveni klon ()
Prejšnjega primera ni bilo treba preglasiti klon ()
ker koda, ki kliče klon ()
se nahaja v razredu, ki se klonira (CloneDemo
). Če klic na klon ()
bili v drugem razredu, potem pa bi morali preglasiti klon ()
. Ker klon ()
je razglašena zaščiten
, bi prejeli "klon je zaščitil dostop v objektu", če ga niste preglasili pred sestavljanjem razreda. V seznamu 4 je predstavljen prenovljeni seznam 3, ki prikazuje preglasitev klon ()
.
Seznam 4. Kloniranje predmeta iz drugega razreda
razred Data implementira Cloneable {int x; @Override public Object clone () vrže CloneNotSupportedException {return super.clone (); }} razred CloneDemo {public static void main (String [] args) vrže CloneNotSupportedException {Data data = new Data (); data.x = 5; System.out.println ("data.x =" + data.x); Podatki data2 = (Data) data.clone (); System.out.println ("data2.x =" + data2.x); }}
Seznam 4 navaja a Podatki
razred, katerega primerke je treba klonirati. Podatki
izvaja Klonirano
vmesnik za preprečevanje CloneNotSupportedException
pred metanjem, ko klon ()
metoda se imenuje. Nato izjavi int
polje na osnovi primerka x
, in preglasi klon ()
metoda. The klon ()
metoda se izvrši super.clone ()
da pokliče svoj superrazred (to je, Predmet
's) klon ()
metoda. Prevladujoče klon ()
metoda identificira CloneNotSupportedException
v svojem meti
klavzulo.
Seznam 4 navaja tudi a CloneDemo
razred, ki: ustvari primerke Podatki
, inicializira svoje polje primerka, izpiše vrednost polja primerka, klonira Podatki
objekt in izpiše vrednost polja primerka.
Sestavi seznam 4 (javac CloneDemo.java
) in zaženite aplikacijo (java CloneDemo
). Upoštevati morate naslednje rezultate:
data.x = 5 data2.x = 5
Plitvo kloniranje
Plitvo kloniranje (poznan tudi kot plitvo kopiranje) se nanaša na podvajanje področij predmeta, ne da bi podvojil predmete, na katere se sklicujejo referenčna polja tega predmeta (če obstajajo referenčna polja). Navedba 3 in 4 je dejansko pokazala plitvo kloniranje. Vsak od cd
-, cd2
-, podatkov
-, in podatki2
-referencirana polja identificirajo objekt, ki ima svojo kopijo int
-temelji x
polje.
Plitvo kloniranje dobro deluje, če so vsa polja prvotnega tipa in (v mnogih primerih), kadar se sklicujejo katera koli referenčna polja nespremenljiv (nespremenljivi) predmeti. Če pa je kateri koli predmet, na katerega se sklicuje, spremenljiv, lahko prvotni predmet in njegovi kloni (-i) vidijo spremembe, ki jih naredi kateri koli od teh predmetov. Seznam 5 prikazuje.
Seznam 5. Težava s plitvim kloniranjem v kontekstu referenčnega polja
class Zaposleni izvaja Cloneable {private String name; zasebna int starost; zasebni naslov; Zaposleni (ime niza, starost, naslov) {this.name = ime; this.age = starost; this.address = naslov; } @Override public Object clone () vrže CloneNotSupportedException {return super.clone (); } Naslov getAddress () {povratni naslov; } String getName () {return ime; } int getAge () {vrnitev starosti; }} naslov naslova {private String city; Naslov (niz mesta) {this.city = city; } String getCity () {return city; } void setCity (String city) {this.city = city; }} razred CloneDemo {public static void main (String [] args) vrže CloneNotSupportedException {Employee e = new Employee ("John Doe", 49, nov naslov ("Denver")); System.out.println (e.getName () + ":" + e.getAge () + ":" + e.getAddress (). GetCity ()); Zaposlen e2 = (Zaposlen) 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 ()); }}
Seznam 5 predstavlja Zaposleni
, Naslov
, in CloneDemo
razredih. Zaposleni
izjavlja ime
, starost
, in naslov
polja; in ga je mogoče klonirati. Naslov
razglasi naslov mesta, katerega primeri so spremenljivi. CloneDemo
poganja aplikacijo.
CloneDemo
je glavni ()
metoda ustvari Zaposleni
objekt in ga klonira. Nato spremeni ime mesta v izvirniku Zaposleni
predmeta naslov
polje. Ker oboje Zaposleni
predmeti se sklicujejo na isto Naslov
objekt, spremenjeno mesto vidijo oba predmeta.
Sestavi seznam 5 (javac CloneDemo.java
) in zaženite to aplikacijo (java CloneDemo
). Upoštevati morate naslednje rezultate:
John Doe: 49: Denver John Doe: 49: Denver John Doe: 49: Chicago John Doe: 49: Chicago
Globoko kloniranje
Globoko kloniranje (poznan tudi kot globoko kopiranje) se nanaša na podvajanje predmetnih polj, tako da so vsi predmeti, na katere se sklicuje, podvojeni. Poleg tega se referenčni objekti referenčnih predmetov podvajajo itd. Seznam 6 refaktorjev Seznam 5 za prikaz globokega kloniranja.
Seznam 6. Globoko kloniranje naslovnega polja
class Zaposleni izvaja Cloneable {private String name; zasebna int starost; naslov zasebnega naslova; Zaposleni (Ime niza, starost, naslov, naslov) {this.name = ime; this.age = starost; this.address = naslov; } @Override public Object clone () vrže CloneNotSupportedException {zaposleni e = (zaposleni) super.clone (); e.address = (Address) address.clone (); vrnitev e; } Naslov getAddress () {povratni naslov; } String getName () {return ime; } int getAge () {vrnitev starosti; }} naslov naslova {private String city; Naslov (niz mesta) {this.city = city; } @Override public Object clone () {vrni nov naslov (nov niz (mesto)); } String getCity () {return city; } void setCity (String city) {this.city = city; }} razred CloneDemo {public static void main (String [] args) vrže CloneNotSupportedException {Employee e = new Employee ("John Doe", 49, nov naslov ("Denver")); System.out.println (e.getName () + ":" + e.getAge () + ":" + e.getAddress (). GetCity ()); Zaposlen e2 = (Zaposlen) 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 ()); }}
Seznam 6 to kaže Zaposleni
je klon ()
metoda najprej pokliče super.clone ()
, ki plitko kopira ime
, starost
, in naslov
polja. Nato pokliče klon ()
na naslov
polje, da naredite dvojnik sklica Naslov
predmet. Naslov
preglasi klon ()
metoda in razkrije nekaj razlik od prejšnjih razredov, ki preglasijo to metodo:
Naslov
se ne izvajaKlonirano
. Ni nujno, ker samoPredmet
jeklon ()
metoda zahteva, da razred izvaja ta vmesnik in toklon ()
metoda ni poklicana.- Prevladujoče
klon ()
metoda ne vržeCloneNotSupportedException
. Ta izjema je vržena samo izPredmet
jeklon ()
metoda, ki se ne imenuje. Zato izjeme ni treba obdelati ali ji poslati mimo klica metode prek klavzule throws. Predmet
jeklon ()
metoda ni poklicana (nisuper.clone ()
klic), ker plitko kopiranje zaNaslov
razred - kopirate lahko samo eno polje.