Programiranje

Statični razredi in notranji razredi v Javi

Vgnezdeni razredi so razredi, ki so prijavljeni kot člani drugih razredov ali obsegov. Uganjanje razredov je eden od načinov za boljšo organizacijo kode. Recimo na primer, da imate ugnezden razred (znan tudi kot vrhunski razred), ki shranjuje predmete v spremenljivo matriko, čemur sledi razred iteratorja, ki vrne vsak predmet. Namesto da bi onesnažili imenski prostor razreda najvišje ravni, bi lahko razred iteratorja razglasil kot člana razreda zbirke matrike, ki jo je mogoče spremeniti. To deluje, ker sta oba tesno povezana.

V Javi so ugnezdeni razredi kategorizirani kot bodisi statični razredi članov ali notranji razredi. Notranji razredi so nestatični razredi članov, lokalni razredi ali anonimni razredi. V tej vadnici boste izvedeli, kako delati s statičnimi razredi članov in tremi vrstami notranjih razredov v kodi Java.

Izogibajte se puščanju pomnilnika v ugnezdenih razredih

Oglejte si tudi namig Java, povezan s to vadnico, kjer boste izvedeli, zakaj so ugnezdeni razredi ranljivi za uhajanje pomnilnika.

Statični razredi v Javi

V mojem Java 101 vaje Razredi in predmeti v Javi ste se naučili, kako statična polja in statične metode prijaviti kot člane razreda. V inicializaciji razredov in predmetov v Javi ste se naučili, kako statične inicializatorje prijaviti kot člane razreda. Zdaj se boste naučili, kako prijaviti statični razredi. Formalno znan kot statični razredi članov, to so ugnezdeni razredi, ki jih prijavite na isti ravni kot te druge statične entitete z uporabo statično ključna beseda. Tu je primer statične izjave razreda člana:

 razred C {static int f; statična praznina m () {} statična {f = 2; } statični razred D {// člani}} 

Ta primer uvaja razred najvišje ravni C s statičnim poljem f, statična metoda m (), statični inicializator in statični razred D. Opazite to D je član C. Statično polje f, statična metoda m (), in statični inicializator sta tudi člana C. Ker vsi ti elementi pripadajo razredu C, je znan kot ogradni razred. Razred D je znan kot zaprti razred.

Pravila za ograjevanje in dostop

Čeprav je zaprt, statični članski razred ne more dostopati do polj primerka razreda in priklicati njegove metode primerka. Lahko pa dostopa do statičnih polj zaprtega razreda in prikliče njegove statične metode, tudi tiste člane, ki so deklarirani zasebno. Za prikaz, seznam 1 razglasi EnclosingClass z ugnezdenim SMClass.

Seznam 1. Izjava o statičnem razredu člana (EnclosingClass.java, različica 1)

 razred EnclosingClass {zasebni statični niz s; zasebna statična praznina m1 () {System.out.println (s); } statična praznina m2 () {SMClass.accessEnclosingClass (); } statični razred SMClass {static void accessEnclosingClass () {s = "Poklican iz metode SMClass accessEnclosingClass ()"; m1 (); } void accessEnclosingClass2 () {m2 (); }}} 

V seznamu 1 je naveden razred najvišje ravni z imenom EnclosingClass s predavalnim poljem s, razredne metode m1 () in m2 ()in razred statičnega člana SMClass. SMClass razglasi metodo razreda accessEnclosingClass () in primerka accessEnclosingClass2 (). Upoštevajte naslednje:

  • m2 ()je priklic SMClassje accessEnclosingClass () metoda zahteva SMClass. predpono, ker accessEnclosingClass () je razglašena statično.
  • accessEnclosingClass () lahko dostopa EnclosingClassje s polje in pokličite njegovo m1 () metoda, čeprav sta bili obe razglašeni zasebno.

Seznam 2 predstavlja izvorno kodo SMCDemo aplikacijski razred, ki prikazuje, kako sklicati SMClassje accessEnclosingClass () metoda. Prav tako prikazuje, kako narediti primerek SMClass in prikličete njegovo accessEnclosingClass2 () metoda primerka.

Seznam 2. Klicanje metod statičnega člana (SMCDemo.java)

 javni razred SMCDemo {public static void main (String [] args) {EnclosingClass.SMClass.accessEnclosingClass (); EnclosingClass.SMClass smc = novo EnclosingClass.SMClass (); smc.accessEnclosingClass2 (); }} 

Kot je prikazano v seznamu 2, če želite priklicati metodo najvišjega razreda iz zaprtega razreda, morate pred imenom predpisanega razreda dodati ime njegovega zaprtega razreda. Če želite primeriti zaprti razred, morate pred imenom predpisa dodati ime njegovega zaprtega razreda. Nato lahko prikličete metodo primerka na običajen način.

Sestavi seznam 1 in 2, kot sledi:

 javac * .java 

Ko prevedete zaprti razred, ki vsebuje razred statičnega člana, prevajalnik ustvari datoteko razreda za razred statičnega člana, katerega ime je sestavljeno iz imena njegovega razreda, znaka za dolar in imena razreda statičnega člana. V tem primeru je sestavljanje rezultatov v EnclosingClass $ SMCClass.class in EnclosingClass.class.

Zaženite aplikacijo na naslednji način:

 java SMCDemo 

Upoštevati morate naslednje rezultate:

 Klicano iz metode SMClass's accessEnclosingClass () Klicano iz metode SMClass's accessEnclosingClass () 

Primer: Statični razredi in Java 2D

Java knjižnica standardnih razredov je izvajalna knjižnica datotek razredov, ki shranjujejo prevedene razrede in druge referenčne vrste. Knjižnica vključuje številne primere statičnih učnih razredov, nekatere pa najdemo v razredih 2D geometrijskih oblik Java, ki se nahajajo v java.awt.geom paket. (O paketih boste izvedeli v naslednjem Java 101 vadnico.)

The Ellipse2D razred najden v java.awt.geom opisuje elipso, ki je definirana z okvirjalnim pravokotnikom v smislu (x, y) zgornjega levega kota skupaj s širino in višino. Naslednji fragment kode kaže, da temelji arhitektura tega razreda Float in Dvojno statični članski razredi, ki sta podrazred Ellipse2D:

 javni abstraktni razred Ellipse2D razširja RectangularShape {javni statični razred Float razširja Ellipse2D izvaja Serializable {javni float x, y, širina, višina; public Float () {} public Float (float x, float y, float w, float h) {setFrame (x, y, w, h); } javni dvojni getX () {return (dvojni) x; } // metode dodatnih primerov} javni statični razred Double extends Ellipse2D implementira Serializable {public double x, y, width, height; public Double () {} public Double (dvojni x, dvojni y, dvojni w, dvojni h) {setFrame (x, y, w, h); } javni dvojni getX () {return x; } // dodatne metode primerka} javna logična vrednost vsebuje (dvojni x, dvojni y) {// ...} // dodatne metode primerka, ki jih delijo podrazredi Float, Double in drugi // Ellipse2D} 

The Float in Dvojno razredi podaljšajo Ellipse2D, ki zagotavlja plavajočo vejico in plavajočo vejico z dvojno natančnostjo Ellipse2D izvedb. Razvijalci uporabljajo Float za zmanjšanje porabe pomnilnika, zlasti ker boste morda potrebovali na tisoče ali več teh predmetov za izdelavo ene same 2D scene. Uporabljamo Dvojno kadar je potrebna večja natančnost.

Izvlečka ne morete ustvariti s primerkom Ellipse2D razreda, lahko pa ustvarite primere Float ali Dvojno. Lahko tudi podaljšate Ellipse2D za opis oblike po meri, ki temelji na elipsi.

Kot primer recimo, da želite predstaviti a Krog2D razred, ki ni prisoten v java.awt.geom paket. Naslednji fragment kode prikazuje, kako bi ustvarili datoteko Ellipse2D objekt z izvedbo s plavajočo vejico:

 Ellipse2D e2d = novo Ellipse2D.Float (10.0f, 10.0f, 20.0f, 30.0f); 

Naslednji fragment kode prikazuje, kako bi ustvarili datoteko Ellipse2D objekt z dvojno natančnostjo izvedbe s plavajočo vejico:

 Ellipse2D e2d = nova Ellipse2D.Dvojna (10,0, 10,0, 20,0, 30,0); 

Zdaj lahko prikličete katero koli metodo, navedeno v Float ali Dvojno s klicanjem metode na vrnjenem Ellipse2D sklic (npr. e2d.getX ()). Na enak način se lahko sklicujete na katero koli skupno metodo Float in Dvojno, in ki so prijavljeni v Ellipse2D. Primer je:

 e2d. vsebuje (2.0, 3.0) 

S tem je uvod v statične razrede članov zaključen. Nato si bomo ogledali notranje razrede, ki so nestatični razredi članov, lokalni razredi ali anonimni razredi. Naučili se boste delati z vsemi tremi vrstami notranjega razreda.

prenos Prenesite kodo Prenesite izvorno kodo za primere v tej vadnici. Ustvaril Jeff Friesen za JavaWorld.

Notranji razredi, tip 1: Nestatični razredi članov

Že prej ste se naučili v Java 101 serija, kako razglasiti nestatična (primer) polja, metode in konstruktorje kot člane razreda. Lahko tudi prijavite nestatični razredi članov, ki so ugnezdeni nestatični razredi, ki jih prijavite na isti ravni kot polja primerka, metode in konstruktorji. Razmislite o tem primeru:

 razred C {int f; praznina m () {} C () {f = 2; } razred D {// člani}} 

Tu predstavljamo razred najvišje stopnje C s primerom polja f, metoda primerka m (), konstruktor in nestatični članski razred D. Vse te entitete so člani razreda C, ki jih obdaja. Vendar pa so te entitete, za razliko od prejšnjega primera, povezane z primeriC in ne z C razred sam.

Vsak primerek nestatičnega razreda člana je implicitno povezan z primerkom njegovega zaprtega razreda. Metode primerkov nestatičnega člana lahko pokličejo metode primerka zaprtega razreda in dostopajo do njegovih polj primerka. Za prikaz tega dostopa seznam 3 razglasi EnclosingClass z ugnezdenim NSMClass.

Seznam 3. Razglasite zaprti razred z ugnezdenim ne-statičnim članskim razredom (EnclosingClass.java, različica 2)

 razred EnclosingClass {private String s; zasebna praznina m () {System.out.println (s); } razred NSMClass {void accessEnclosingClass () {s = "Poklican iz metode accessEnclosingClass () NSMClass"; m (); }}} 

V seznamu 3 je razglašen najvišji razred z imenom EnclosingClass s primerom polja s, metoda primerka m ()in nestatični razred NSMClass. Poleg tega NSMClass razglasi metodo primerka accessEnclosingClass ().

Ker accessEnclosingClass () je nestatičen, NSMClass mora biti instanciran, preden je to metodo mogoče poklicati. Ta primerek mora biti izveden prek primerka EnclosingClass, kot je prikazano na seznamu 4.

Seznam 4. NSMCDemo.java

 javni razred NSMCDemo {public static void main (String [] args) {EnclosingClass ec = new EnclosingClass (); ec.new NSMClass (). accessEnclosingClass (); }} 

Seznam 4 glavni () metoda najprej ustvari primerek EnclosingClass in sklic shrani v lokalno spremenljivko ek. The glavni () metoda nato uporabi EnclosingClass sklic kot predpono novo operater, da ustvari primerek NSMClass. The NSMClass referenca se nato uporabi za klic accessEnclosingClass ().

Ali naj uporabim 'new' s sklicevanjem na razred ograde?

Predpona novo s sklicevanjem na zaprti razred je redek. Namesto tega običajno pokličete konstruktor zaprtega razreda znotraj konstruktorja ali metode primerka njegovega zaprtega razreda.

Sestavi seznam 3 in 4, kot sledi:

 javac * .java 

Ko prevedete ogradni razred, ki vsebuje ne-statični razred, prevajalnik ustvari datoteko razreda za ne-statični razred, katerega ime je sestavljeno iz imena njegovega razreda, znaka za dolar in ne-statičnega razreda. ime. V tem primeru je sestavljanje rezultatov v EnclosingClass $ NSMCClass.class in EnclosingClass.class.

Zaženite aplikacijo na naslednji način:

 java NSMCDemo 

Upoštevati morate naslednje rezultate:

 Klicano iz metode accessEnclosingClass () NSMClass 

Kdaj (in kako) izpolniti pogoje za "to"

Koda zaprtega razreda lahko s kvalificirano rezervirano besedo pridobi referenco na svoj primerek zaprtega razreda to z imenom priloženega razreda in operaterjem dostopa do člana (.). Na primer, če je koda znotraj accessEnclosingClass () potreben za sklic na njegovo EnclosingClass primer, bi določil EnclosingClass.this. Ker prevajalnik za to nalogo ustvari kodo, je določanje te predpone redko.

Primer: Nestatični razredi članov v HashMap-u

Standardna knjižnica razredov vključuje tudi nestatične razrede članov in razrede statičnih članov. Za ta primer si bomo ogledali HashMap razred, ki je del ogrodja zbirk Java v java.util paket. HashMap, ki opisuje izvedbo zemljevida na osnovi razprševalne tabele, vključuje več nestatičnih razredov članov.

Na primer KeySet nestatični članski razred opisuje niz, ki temelji pogled tipk na zemljevidu. Naslednji fragment kode se nanaša na priloženi KeySet razred do svojega HashMap ogradni razred:

 javni razred HashMap razširja AbstractMap izvaja Map, Cloneable, Serializable {// različni člani končni razred KeySet razširja AbstractSet {// različni člani} // različni člani} 

The in sintakse so primeri generiki, zbirka sorodnih jezikovnih funkcij, ki pomagajo prevajalniku uveljaviti varnost tipa. V prihodnosti bom predstavil generike Java 101 vadnica. Zaenkrat morate le vedeti, da te sintakse pomagajo prevajalniku uveljaviti vrsto ključnih predmetov, ki jih je mogoče shraniti na zemljevidu in v nabor ključev, ter vrsto predmetov vrednosti, ki jih je mogoče shraniti na zemljevidu.

HashMap zagotavlja a keySet () metoda, ki ustvari primerek KeySet po potrebi vrne ta primerek ali predpomnjeni primerek. Tu je celotna metoda:

$config[zx-auto] not found$config[zx-overlay] not found