Programavimas

Klasių ir objektų inicijavimas „Java“

Prieš naudojant, „Java“ klasės ir objektai turi būti inicializuoti. Anksčiau sužinojote, kad klasių laukai yra inicializuojami pagal numatytąsias reikšmes, kai įkeliamos klasės, ir kad objektai inicijuojami per konstruktorius, tačiau inicializavimo yra daugiau. Šiame straipsnyje pateikiamos visos „Java“ funkcijos, skirtos inicijuoti klases ir objektus.

atsisiųsti Gauti kodą Atsisiųskite šaltinį, pvz., programas, šioje pamokoje. Sukūrė Jeffas Friesenas, skirtas „JavaWorld“.

Kaip inicijuoti „Java“ klasę

Prieš tyrinėdami „Java“ palaikymą klasės inicializavimui, pakartokime „Java“ klasės inicializavimo veiksmus. Apsvarstykite 1 sąrašą.

Sąrašas 1. Inicijuojami klasės laukai pagal numatytąsias reikšmes

klasė SomeClass {statinis loginis b; statinis baitas; statinis char c; statinis dvigubas d; statinė plūdė f; statinis int i; statinis ilgas l; statiniai trumpieji s; statinis Styginių g. }

1 sąrašas deklaruoja klasę SomeClass. Ši klasė deklaruoja devynis tipų laukus loginis, baitas, char, dvigubai, plūdė, tarpt, ilgas, trumpasir Stygos. Kada SomeClass yra įkeltas, kiekvieno lauko bitai nustatomi į nulį, kurį interpretuojate taip:

klaidingas 0 \ u0000 0.0 0.0 0 0 0 null

Ankstesni klasės laukai buvo netiesiogiai inicijuoti iki nulio. Tačiau taip pat galite aiškiai inicijuoti klasės laukus, tiesiogiai priskirdami jiems vertes, kaip parodyta 2 sąraše.

Sąrašas 2. Inicijuojami klasės laukai, kad būtų aiškios reikšmės

klasė SomeClass {statinis loginis b = teisingas; statinis baitas = 1; statinė char c = 'A'; statinis dvigubas d = 2,0; statinė plūdė f = 3,0f; statinis int i = 4; statinis ilgis l = 5000000000L; statinis trumpasis s = 20000; statinė eilutė st = "abc"; }

Kiekvienos užduoties vertė turi būti suderinama su klasės lauko tipu. Kiekvienas kintamasis įrašo vertę tiesiogiai, išskyrus šv. Kintamas šv saugo nuorodą į a Stygos objektas, kuriame yra abc.

Nurodomi klasės laukai

Inicijuojant klasės lauką, teisėta jį inicijuoti pagal anksčiau inicijuoto klasės lauko vertę. Pavyzdžiui, inicijuojamas 3 sąrašas y į xvertė. Abu laukai inicijuojami 2.

Sąrašas 3. Nuoroda į anksčiau deklaruotą lauką

klasė SomeClass {static int x = 2; statinis int y = x; public static void main (String [] args) {System.out.println (x); System.out.println (y); }}

Tačiau atvirkščiai nėra teisėta: negalima inicijuoti klasės lauko pagal vėliau deklaruoto klasės lauko vertę. „Java“ kompiliatoriaus išvestys neteisėta išankstinė nuoroda kai susiduria su šiuo scenarijumi. Apsvarstykite 4 sąrašą.

Sąrašas 4. Bandymas nurodyti vėliau deklaruotą lauką

klasė SomeClass {static int x = y; statinis int y = 2; public static void main (String [] args) {System.out.println (x); System.out.println (y); }}

Kompiliatorius praneš neteisėta išankstinė nuoroda kai susiduria statinis int x = y;. Taip yra todėl, kad šaltinio kodas yra sudarytas iš viršaus į apačią, o kompiliatorius dar nematė y. (Tai taip pat išleistų šį pranešimą, jei y nebuvo aiškiai inicijuota.)

Klasės inicializavimo blokai

Kai kuriais atvejais galbūt norėsite atlikti sudėtingus klasių inicializavimus. Tai atliksite po to, kai klasė bus įkelta ir prieš kuriant bet kokius objektus iš tos klasės (darant prielaidą, kad klasė nėra naudingumo klasė). Šiai užduočiai galite naudoti klasės inicialų bloką.

A klasės inicializavimo blokas yra teiginių blokas, prieš kurį rašoma statinis raktinis žodis, įvestas į klasės kūną. Kai klasė įkeliama, šie sakiniai vykdomi. Apsvarstykite 5 sąrašą.

Sąrašas 5. Inicijuojami sinuso ir kosinuso reikšmių masyvai

klasės grafika {statiniai dvigubi [] sinusai, kosinusai; statinis {sinusai = naujas dvigubas [360]; kosinusas = naujas dvigubas [360]; už (int i = 0; i <sinusų.ilgis; i ++) {sinusai [i] = Math.sin (Math.toRadians (i)); kosinusai [i] = Math.cos (Math.toRadians (i)); }}}

5 sąrašas skelbia a Grafika klasė, kuri deklaruoja sinusai ir kosinusai masyvo kintamieji. Ji taip pat deklaruoja klasės inicializavimo bloką, kuris sukuria 360 elementų masyvus, kuriems priskiriamos nuorodos sinusai ir kosinusai. Tada jis naudoja a dėl sakinys inicializuoti šiuos masyvo elementus iki atitinkamų sinusų ir kosinusų reikšmių, iškviečiant Matematika klasės nuodėmė () ir cos () metodai. (Matematika yra „Java“ standartinės klasės bibliotekos dalis. Aptarsiu šią klasę ir šiuos metodus būsimame straipsnyje.)

Veiklos triukas

Kadangi grafikos programoms našumas yra svarbus ir kad greičiau pasiekti masyvo elementą nei iškviesti metodą, kūrėjai griebiasi našumo gudrybių, tokių kaip sinusų ir kosinusų masyvų kūrimas ir inicijavimas.

Derinant klasės lauko inicialus ir klasės inicijavimo blokus

Programoje galite sujungti kelis klasės lauko iniciatorius ir klasės inicializavimo blokus. 6 sąrašas pateikia pavyzdį.

Sąrašas 6. Vykdant klasės inicijavimą iš viršaus į apačią

klasė MCFICIB {static int x = 10; statinė dviguba temperatūra = 98,6; statinis {System.out.println ("x =" + x); temp = (temp - 32) * 5,0 / 9,0; // konvertuoti į Celsijaus sistemą.out.println ("temp =" + temp); } statinis int y = x + 5; statinis {System.out.println ("y =" + y); } public static void main (String [] args) {}}

6 sąrašas skelbia ir inicializuoja porą klasės laukų (x ir y), ir deklaruoja porą statinis iniciatoriai. Sudarykite šį sąrašą, kaip parodyta:

javac MCFICIB.java

Tada paleiskite gautą programą:

java MCFICIB

Turėtumėte stebėti šį rezultatą:

x = 10 temp = 37,0 y = 15

Ši išvestis atskleidžia, kad klasės inicijavimas atliekamas „iš viršaus į apačią“ tvarka.

() metodai

Kompiliuodamas klasės inicialus ir klasės inicializavimo blokus, „Java“ kompiliatorius sukompiliuotą baitkodą (tvarka iš viršaus į apačią) saugo specialiu metodu, pavadintu (). Kampiniai laikikliai neleidžia a vardų konfliktas: negalite deklaruoti a () metodas šaltinio kode, nes < ir > simboliai yra neteisėti identifikatoriaus kontekste.

Įkėlus klasę, JVM prieš skambindamas iškviečia šį metodą pagrindinis () (kada pagrindinis () yra).

Pažvelkime į vidų MCFICIB.klasė. Šis dalinis išmontavimas atskleidžia saugomą x, tempir y laukai:

Lauko # 1 00000290 Prieigos Vėliavos ACC_STATIC 00.000.292 Vardas x 00000294 deskriptorius Aš 00000296 atributai Count 0 laukas # 2 00000298 Prieigos Vėliavos ACC_STATIC 0000029a Vardas temperatūra 0000029c deskriptorius D 0000029e atributai Count 0 laukas # 3 000002a0 prieigos Vėliavos ACC_STATIC 000002a2 Vardas Y 000002a4 deskriptorius Aš 000002a6 atributai Count 0

Deskriptorius eilutė identifikuoja JVM tipo deskriptorius laukui. Tipą žymi viena raidė: dėl tarpt ir D dėl dvigubai.

Šis dalinis išardymas atskleidžia baito kodo instrukcijų seką () metodas. Kiekviena eilutė prasideda dešimtainiu skaičiumi, kuris identifikuoja tolesnio nurodymo nulinės vertės poslinkio adresą:

 0 dvipusis 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 naujų java / lang / StringBuilder 17 dup 18 invokespecial java / lang / StringBuilder / () V 21 ldc "x =" 23 invokevirtual 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 invokevirtual 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 naujas java / lang / StringBuilder 62 dup 63 invokespecial java / lang / StringBuilder / () V 66 ldc "temp =" 68 invokevirtual java / lang / StringBuilder / append (Ljava / lang / String;) Ljava / lang / StringBuilder; 71 getstatic MCFICIB / temp D 74 invokevirtual 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 naujas java / lang / StringBuilder 97 dup 98 invokespecial java / lang / StringBuilder / () V 101 ldc "y =" 103 invokevirtual 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 grįžti

Komandų seka nuo 0 poslinkio iki 2 poslinkio prilygsta tokiam klasės lauko iniciatoriui:

statinis int x = 10;

Instrukcijų seka nuo 5 poslinkio iki 8 poslinkio prilygsta tokiam klasės lauko iniciatoriui:

statinė dviguba temperatūra = 98,6;

Komandų seka nuo 11 poslinkio iki 80 poslinkio prilygsta šiam klasės inicializavimo blokui:

statinis {System.out.println ("x =" + x); temp = (temp - 32) * 5,0 / 9,0; // konvertuoti į Celsijaus sistemą.out.println ("temp =" + temp); }

Komandų seka nuo 83 poslinkio iki 88 poslinkio yra ekvivalenti tokiam klasės lauko iniciatoriui:

statinis int y = x + 5;

Nurodymų seka nuo 91 poslinkio iki 115 poslinkio yra lygi tokiam klasės inicializavimo blokui:

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

Galiausiai grįžti instrukcija 118 poslinkyje grąžina vykdymą iš () į tą JVM dalį, kuri vadino šį metodą.

Nesijaudinkite, ką reiškia baitų kodas

Iš šio pratimo reikia įsitikinti, kad visi 6 sąrašo klasės lauko iniciatorių ir klasės inicializavimo blokų kodai yra () metodas, ir vykdomas „iš viršaus į apačią“ tvarka.

Kaip inicijuoti objektus

Po to, kai klasė buvo įkelta ir inicializuota, dažnai norėsite sukurti klasės objektus. Kaip jūs sužinojote mano naujausioje programavimo su klasėmis ir objektais įžangoje, jūs inicijuojate objektą naudodami kodą, kurį įdedate į klasės konstruktorių. Apsvarstykite 7 sąrašą.

Sąrašas 7. Konstruktoriaus naudojimas objektui inicializuoti

klasė Miestas {privatus eilutės pavadinimas; int populiacija; Miestas (eilutės pavadinimas, gyventojų skaičius) {this.name = vardas; tai.populiacija = populiacija; } @Paisyti viešosios eilutės toString () {return name + ":" + populiacija; } public static void main (String [] args) {Miestas newYork = naujas miestas ("Niujorkas", 8491079); System.out.println (newYork); // Išvestis: Niujorkas: 8491079}}

7 sąrašas skelbia a Miestas klasė su vardas ir gyventojų laukai. Kada Miestas sukurtas objektas, Miestas (eilutės pavadinimas, gyventojų skaičius) konstruktorius kviečiamas inicializuoti šiuos laukus pagal iškviesto konstruktoriaus argumentus. (Aš taip pat nepaisiau Objektas's viešoji styginių eilutė () metodas patogiai grąžinti miesto pavadinimą ir gyventojų vertę kaip eilutę. System.out.println () galų gale iškviečia šį metodą, kad grąžintų objekto eilutės atvaizdą, kurį jis pateikia.)

Prieš skambinant konstruktoriui, kokias reikšmes daro vardas ir gyventojų turėti? Tai galite sužinoti įterpdami System.out.println (this.name); System.out.println (tai populiacija); prasidėjus konstruktoriui. Sudarius šaltinio kodą (javac City.java) ir paleisti programą (java miestas), jūs pastebėtumėte niekinis dėl vardas ir 0 dėl gyventojų. naujas operatorius nuleidžia objekto objekto (egzemplioriaus) laukus prieš vykdydamas konstruktorių.

Kaip ir klasės laukuose, galite aiškiai inicijuoti objekto laukus. Pavyzdžiui, galite nurodyti Stygos pavadinimas = "Niujorkas"; arba int populiacija = 8491079;. Tačiau tai padarius paprastai nėra ko gauti, nes šie laukai bus inicializuoti konstruktoriuje. Vienintelis pranašumas, kurį galiu sugalvoti, yra numatytosios reikšmės priskyrimas objekto laukui; ši reikšmė naudojama iškviečiant konstruktorių, kuris neinicijuoja lauko:

int numDoors = 4; // numatytoji reikšmė priskirta numDoors Car (String make, String model, int metai) {this (markė, modelis, metai, numDoors); } Automobilis (Styginių markė, Styginių modelis, int metai, int numDoors) {this.make = markė; tai.modelis = modelis; tai.metai = metai; this.numDoors = numDoors; }

Objekto inicijavimas atspindi klasės inicializavimą