Ohjelmointi

Luokan ja objektin alustus Java-tilassa

Jaavan luokat ja objektit on alustettava ennen niiden käyttöä. Olet aiemmin oppinut, että luokan kentät alustetaan oletusarvoihin, kun luokat ladataan, ja että objektit alustetaan rakentajien kautta, mutta alustuksessa on enemmän. Tässä artikkelissa esitellään kaikki Java-ominaisuudet luokkien ja objektien alustamiseen.

lataa Hanki koodi Lataa lähdekoodi esimerkiksi sovelluksiin tässä opetusohjelmassa. Luonut Jeff Friesen JavaWorldille.

Java-luokan alustaminen

Ennen kuin tutkimme Java-tukea luokan alustamiseen, kerrotaan uudelleen Java-luokan alustamisen vaiheet. Harkitse listaa 1.

Luettelointi 1. Alustetaan luokan kentät oletusarvoihin

luokka SomeClass {staattinen looginen b; staattinen tavu; staattinen hiili; staattinen kaksois-d; staattinen uimuri f; staattinen int i; staattinen pitkä l; staattiset lyhyet s; staattinen merkkijono st; }

Listaus 1 ilmoittaa luokan JotkutLuokka. Tämä luokka ilmoittaa yhdeksän tyyppikenttää looginen, tavu, hiiltyä, kaksinkertainen, kellua, int, pitkä, lyhytja Merkkijono. Kun JotkutLuokka on ladattu, kunkin kentän bitit asetetaan nollaksi, jonka tulkitset seuraavasti:

väärä 0 \ u0000 0.0 0.0 0 0 0 null

Aikaisemmat luokan kentät alustettiin implisiittisesti nollaan. Voit kuitenkin alustaa myös nimenomaisesti luokkakentät osoittamalla niihin suoraan arvoja, kuten luettelossa 2 on esitetty.

Listaus 2. Alustetaan luokan kentät eksplisiittisiin arvoihin

luokka SomeClass {staattinen looginen b = tosi; staattinen tavu = 1; staattinen merkki c = 'A'; staattinen kaksois-d = 2,0; staattinen uimuri f = 3,0f; staattinen int i = 4; staattinen pitkä l = 5000000000L; staattinen lyhyt s = 20000; staattinen merkkijono st = "abc"; }

Jokaisen tehtävän arvon on oltava tyypin kanssa yhteensopiva luokan kentän tyypin kanssa. Jokainen muuttuja tallentaa arvon suoraan, lukuun ottamatta st. Vaihteleva st tallentaa viittauksen a Merkkijono esine, joka sisältää abc.

Viitataan luokan kenttiin

Alustettaessa luokan kenttää on laillista alustaa se aiemmin alustetun luokan kentän arvoon. Esimerkiksi Listing 3 alustetaan y että xarvo. Molemmat kentät alustetaan 2.

Luettelo 3. Viitataan aiemmin ilmoitettuun kenttään

luokka SomeClass {staattinen int x = 2; staattinen int y = x; public static void main (Merkkijono [] argumentit) {System.out.println (x); System.out.println (y); }}

Käänteinen ei kuitenkaan ole laillista: luokkakenttää ei voi alustaa myöhemmin ilmoitetun luokkakentän arvoon. Java-kääntäjä tuottaa laiton eteenpäin viittaus kun se kohtaa tämän skenaarion. Harkitse listaa 4.

Luettelo 4. Yritetään viitata myöhemmin ilmoitettuun kenttään

luokka SomeClass {staattinen int x = y; staattinen int y = 2; public static void main (Merkkijono [] argumentit) {System.out.println (x); System.out.println (y); }}

Kääntäjä raportoi laiton eteenpäin viittaus kun se kohtaa staattinen int x = y;. Tämä johtuu siitä, että lähdekoodi käännetään ylhäältä alas, eikä kääntäjä ole vielä nähnyt y. (Se antaisi myös tämän viestin, jos y ei nimenomaisesti alustettu.)

Luokan alustuslohkot

Joissakin tapauksissa saatat haluta suorittaa monimutkaisia ​​luokkiin perustuvia alustuksia. Teet tämän sen jälkeen, kun luokka on ladattu ja ennen kuin objektista on luotu kyseisestä luokasta (olettaen, että luokka ei ole apuohjelma). Voit käyttää luokan alustuslohkoa tähän tehtävään.

A luokan alustuslohko on lausejoukko, jota edeltää staattinen avainsana, joka lisätään luokan kehoon. Kun luokka latautuu, nämä lauseet suoritetaan. Harkitse listaa 5.

Listaus 5. Sinus- ja kosini-arvoryhmien alustaminen

luokan grafiikka {staattiset kaksoissinit], kosinit; staattinen {sines = uusi kaksinkertainen [360]; kosinit = uusi kaksinkertainen [360]; for (int i = 0; i <sini.pituus; i ++) {sinit [i] = matematiikka (mat. radiaaneille (i)); kosinit [i] = Math.cos (matematiikka radiaaneille (i)); }}}

Listaus 5 ilmoittaa a Grafiikka luokka, joka ilmoittaa sinit ja kosinit taulukon muuttujat. Se julistaa myös luokan alustuslohkon, joka luo 360-elementtiset taulukot, joille viitteet on määritetty sinit ja kosinit. Sitten se käyttää a varten lauseke alustaa nämä taulukkoelementit sopiviin sini- ja kosini-arvoihin kutsumalla Matematiikka luokan synti() ja cos () menetelmiä. (Matematiikka on osa Javan vakioluokkikirjastoa. Keskustelen tästä luokasta ja näistä menetelmistä tulevassa artikkelissa.)

Suorituskyky temppu

Koska suorituskyky on tärkeää grafiikkasovelluksille ja koska matriisielementtiin on nopeampi päästä kuin menetelmää kutsumalla, kehittäjät turvautuvat suorituskykytemppuihin, kuten luomaan ja alustamaan sini- ja kosiniryhmät.

Luokkakentän alustusohjelmien ja luokan alustuslohkojen yhdistäminen

Voit yhdistää useita luokkakenttien alustusohjelmia ja luokan alustuslohkoja sovelluksessa. Listaus 6 tarjoaa esimerkin.

Listaus 6. Luokan alustus suoritetaan ylhäältä alas -järjestyksessä

luokka MCFICIB {staattinen int x = 10; staattinen kaksoislämpötila = 98,6; staattinen {System.out.println ("x =" + x); lämpötila = (temp - 32) * 5,0 / 9,0; // muunna Celsius-järjestelmäksi.out.println ("temp =" + temp); staattinen int y = x + 5; staattinen {System.out.println ("y =" + y); } public static void main (Merkkijono [] argumentti) {}}

Listaus 6 ilmoittaa ja alustaa luokan kenttien parin (x ja y), ja ilmoittaa parin staattinen alustajat. Koosta tämä luettelo kuvan mukaisesti:

javac MCFICIB.java

Suorita sitten tuloksena oleva sovellus:

java MCFICIB

Ota huomioon seuraava tulos:

x = 10 lämpötila = 37,0 y = 15

Tämä tulos paljastaa, että luokan alustus suoritetaan ylhäältä alas -järjestyksessä.

() -menetelmät

Käännettäessä luokan alustusohjelmia ja luokan alustuslohkoja Java-kääntäjä tallentaa käännetyn tavukoodin (ylhäältä alas järjestyksessä) erityiseen menetelmään nimeltä (). Kulmakiinnikkeet estävät a nimiristiriita: et voi ilmoittaa a () menetelmä lähdekoodissa, koska < ja > merkit ovat laittomia tunnistekontekstissa.

Luokan lataamisen jälkeen JVM kutsuu tätä menetelmää ennen soittamista main () (kun main () on läsnä).

Katsotaanpa katsomaan sisälle MCFICIB.luokka. Seuraava osittainen purkaminen paljastaa tallennettuja tietoja x, Lämpötilaja y kentät:

Kenttä # 1 00000290 Pääsyliput ACC_STATIC 00000292 Nimi x 00000294 Kuvaaja I 00000296 Attribuuttien määrä 0 Kenttä # 2 00000298 Pääsyliput ACC_STATIC 0000029a Nimilämpötila 0000029c Kuvaaja D 0000029e Attribuutit Luku 0 Kenttä # 3 000002a0 Pääsyliput ACC_STATIC 00 002 0

Kuvaaja rivi tunnistaa JVM: t tyyppikuvaaja kentälle. Tyyppiä edustaa yksi kirjain: Minä varten int ja D. varten kaksinkertainen.

Seuraava osittainen purkaminen paljastaa tavun kooditiedot () menetelmä. Jokainen rivi alkaa desimaaliluvulla, joka tunnistaa seuraavan käskyn nollapohjaisen offsetosoitteen:

 0 kaksisuuntainen 10 2 putstatic MCFICIB / x I 5 ldc2_w # 98.6 8 putstatic MCFICIB / temp D 11 getstatic java / lang / System / out Ljava / io / PrintStream; 14 uutta java / lang / StringBuilder 17 dup 18 invokespecial java / lang / StringBuilder / () V 21 ldc "x =" 23 invokevirtuaalinen java / lang / StringBuilder / append (Ljava / lang / String;) Ljava / lang / StringBuilder; 26 getstatic MCFICIB / x I 29 invokevirtual java / lang / StringBuilder / append (I) Ljava / lang / StringBuilder; 32 invokevirtual java / lang / StringBuilder / toString () Ljava / lang / String; 35 invokevirtuaalinen java / io / PrintStream / println (Ljava / lang / String;) V 38 getstatic MCFICIB / temp D 41 ldc2_w # 32 44 dsub 45 ldc2_w # 5 48 dmul 49 ldc2_w # 9 52 ddiv 53 putstatic MCFICIB / temp D 56 getstatic java / lang / System / out Ljava / io / PrintStream; 59 uutta java / lang / StringBuilder 62 dup 63 invokespecial java / lang / StringBuilder / () V 66 ldc "temp =" 68 invokevirtuaalinen java / lang / StringBuilder / append (Ljava / lang / String;) Ljava / lang / StringBuilder; 71 getstatic MCFICIB / temp D 74 invokevirtuaalinen java / lang / StringBuilder / append (D) Ljava / lang / StringBuilder; 77 invokevirtual java / lang / StringBuilder / toString () Ljava / lang / String; 80 invokevirtual java / io / PrintStream / println (Ljava / lang / String;) V 83 getstatic MCFICIB / x I 86 iconst_5 87 iadd 88 putstatic MCFICIB / y I 91 getstatic java / lang / System / out Ljava / io / PrintStream; 94 uusi java / lang / StringBuilder 97 dup 98 kutsuu erityistä java / lang / StringBuilder / () V 101 ldc "y =" 103 invokevirtuaalinen java / lang / StringBuilder / append (Ljava / lang / String;) Ljava / lang / StringBuilder; 106 getstatic MCFICIB / y I 109 invokevirtual java / lang / StringBuilder / append (I) Ljava / lang / StringBuilder; 112 invokevirtual java / lang / StringBuilder / toString () Ljava / lang / String; 115 invokevirtual java / io / PrintStream / println (Ljava / lang / String;) V 118 return

Käskysarja siirtymästä 0 siirtymään 2 vastaa seuraavaa luokkakentän alustusohjelmaa:

staattinen int x = 10;

Komennon järjestys siirtymästä 5 siirtymään 8 vastaa seuraavaa luokkakentän alustusohjelmaa:

staattinen kaksoislämpötila = 98,6;

Komennon järjestys siirtymästä 11 siirtymään 80 vastaa seuraavaa luokan alustuslohkoa:

staattinen {System.out.println ("x =" + x); lämpötila = (temp - 32) * 5,0 / 9,0; // muunna Celsius-järjestelmäksi.out.println ("temp =" + temp); }

Komennosarja siirtymästä 83 siirtymään 88 vastaa seuraavaa luokkakentän alustusohjelmaa:

staattinen int y = x + 5;

Komennosekvenssi siirtymästä 91 siirtymään 115 vastaa seuraavaa luokan alustuslohkoa:

staattinen {System.out.println ("y =" + y); }

Lopuksi palata käsky siirtymässä 118 palauttaa suorituksen kohdasta () siihen JVM: n osaan, joka kutsui tätä menetelmää.

Älä huoli siitä, mitä tavukoodi tarkoittaa

Tämän harjoituksen takana on nähdä, että kaikki Listing 6: n luokan kentän alustusohjelmien ja luokan alustuslohkojen koodit sijaitsevat () menetelmä, ja se suoritetaan ylhäältä alas -järjestyksessä.

Objektien alustaminen

Kun luokka on ladattu ja alustettu, haluat usein luoda esineitä luokasta. Kuten opit äskettäisessä johdannossani ohjelmoinnista luokkien ja objektien kanssa, alustat objektin koodilla, jonka sijoitat luokan konstruktoriin. Harkitse listaa 7.

Luettelointi 7. Objektin alustaminen konstruktorin avulla

luokka Kaupunki {yksityinen merkkijono nimi; int väestö; Kaupunki (merkkijonon nimi, int väestö) {this.name = nimi; tämä. väestö = väestö; } @Override public String toString () {return name + ":" + populaatio; } public static void main (String [] args) {Kaupunki newYork = uusi kaupunki ("New York", 8491079); System.out.println (newYork); // Tuotos: New York: 8491079}}

Listaus 7 ilmoittaa a Kaupunki luokan kanssa nimi ja väestö kentät. Kun Kaupunki objekti on luotu, Kaupunki (merkkijono, int väestö) konstruktori kutsutaan alustamaan nämä kentät kutsutun konstruktorin argumentteiksi. (Olen myös ohittanut Esineon public String toString () menetelmä palauttaa kaupungin nimi ja väestöarvo kätevästi merkkijonona. System.out.println () lopulta kutsuu tätä menetelmää palauttamaan objektin merkkijonoesityksen, jonka se antaa.)

Mitä arvoja tehdään ennen konstruktorin kutsumista nimi ja väestö sisältää? Voit selvittää lisäämällä System.out.println (tämä.nimi); System.out.println (tämä väestö); rakentajan alussa. Lähdekoodin (javac City.java) ja sovelluksen suorittaminen (java kaupunki), huomaisit tyhjä varten nimi ja 0 varten väestö. Uusi operaattori nollaa objektin objektin (esiintymän) kentät ennen konstruktorin suorittamista.

Kuten luokan kenttien kohdalla, voit alustaa objektikentät nimenomaisesti. Voit esimerkiksi määrittää Merkkijonon nimi = "New York"; tai int väestö = 8491079;. Tällä ei kuitenkaan yleensä ole mitään hyötyä, koska nämä kentät alustetaan konstruktorissa. Ainoa etu, jonka voin ajatella, on oletusarvon määrittäminen objektikentälle; tätä arvoa käytetään, kun soitat rakentajalle, joka ei alusta kenttää:

int num Doors = 4; // oletusarvo määritetty numDoors Carille (String merkki, String malli, int vuosi) {tämä (merkki, malli, vuosi, numDoors); } Auto (merkkijono merkki, merkkijono malli, int vuosi, int numDoors) {this.make = merkki; tämä malli = malli; tämä.vuosi = vuosi; this.numDoors = numDoors; }

Objektin alustus peilaa luokan alustus