1. Változók inicializálása
Mint már tudod, az osztályodban több változót is deklarálhatsz, és nem csak deklarálhatod, hanem azonnal inicializálhatod is a kezdeti értékükkel.
És ugyanezek a változók inicializálhatók egy konstruktorban is. Ez azt jelenti, hogy elméletileg ezekhez a változókhoz kétszer is lehet értéket rendelni. Példa
Kód | jegyzet |
---|---|
|
A age változó kezdeti értéket kap A kezdeti érték felülírásra kerül Az életkor változó eltárolja a kezdeti értékét. |
|
Ez megengedett: az első konstruktor meghívásra kerül |
|
Ez megengedett: a második konstruktor meghívásra kerül |
Ez történik, amikor Cat cat = new Cat("Whiskers", 2);
végrehajtják:
Cat
Létrejön egy objektum- Minden példányváltozó a kezdeti értékével inicializálva van
- A konstruktor meghívása és kódja végrehajtásra kerül.
Más szóval, a változók először megkapják a kezdeti értéküket, és csak ezután kerül végrehajtásra a konstruktor kódja.
2. A változók inicializálásának sorrendje egy osztályban
A változókat nem csupán a konstruktor futása előtt inicializálják, hanem egy jól meghatározott sorrendben inicializálják őket: abban a sorrendben, amelyben deklarálják őket az osztályban.
Nézzünk néhány érdekes kódot:
Kód | jegyzet |
---|---|
|
Ez a kód nem fordítható le, mivel a a
változó létrehozásakor még nincsenek b
és c
változók. De a kódot az alábbiak szerint is megírhatja - ez a kód lefordítható, és jól fog futni .
Kód | jegyzet |
---|---|
|
0 0+2 0+2+3 |
De ne feledje, hogy a kódnak átláthatónak kell lennie a többi fejlesztő számára. Jobb, ha nem használunk ilyen technikákat, mert az rontja a kód olvashatóságát.
Itt emlékeznünk kell arra, hogy mielőtt a változókhoz értéket rendelnénk, alapértelmezett értékük van. A típusnál int
ez nulla.
Amikor a JVM inicializálja a a
változót, egyszerűen hozzárendeli az int típus alapértelmezett értékét: 0.
Amikor eléri a értéket b
, az a változó már ismert lesz, és van értéke, így a JVM 2 értéket rendel hozzá.
És amikor eléri a c
változót, a a
és b
változók már inicializálva lesznek, így a JVM könnyen kiszámítja a kezdeti értéket c
: 0+2+3.
Ha változót hoz létre egy metóduson belül, akkor nem használhatja azt, hacsak korábban nem adott hozzá értéket. De ez nem igaz egy osztály változóira! Ha egy osztály változójához nincs hozzárendelve kezdeti érték, akkor az alapértelmezett érték lesz hozzárendelve.
3. Állandók
Miközben az objektumok létrehozásának módját elemezzük, érdemes kitérni az állandók, azaz a változók inicializálására a módosítóval final
.
Ha egy változóban van final
módosító, akkor kezdőértéket kell hozzárendelni. Ezt már tudod, és nincs ebben semmi meglepő.
De amit nem tudsz, az az, hogy nem kell azonnal hozzárendelni a kezdeti értéket, ha a konstruktorban megadod. Ez tökéletesen működik egy végső változónál. Az egyetlen követelmény az, hogy ha több konstruktora van, akkor minden konstruktorban egy végső változóhoz kell hozzárendelni egy értéket.
Példa:
public class Cat
{
public final int maxAge = 25;
public final int maxWeight;
public Cat (int weight)
{
this.maxWeight = weight; // Assign an initial value to the constant
}
}
4. Kódolás konstruktorban
És még néhány fontos megjegyzés a konstruktorokról. Később, ahogy folytatja a Java tanulását, olyan dolgokkal fog találkozni, mint az öröklődés, a szerializálás, a kivételek stb. Ezek mind különböző mértékben befolyásolják a konstruktorok munkáját. Nincs értelme most mélyen belemerülni ezekbe a témákba, de kötelesek vagyunk legalább érinteni őket.
Például itt van egy fontos megjegyzés a konstruktorokról. Elméletileg bármilyen bonyolultságú kód írható egy konstruktorba. De ne tedd ezt. Példa:
|
Fájl olvasási adatfolyam megnyitása A fájl beolvasása bájttömbbe Mentse el a bájttömböt karakterláncként A fájl tartalmának megjelenítése a képernyőn |
A FilePrinter osztálykonstruktorban azonnal megnyitottunk egy bájtfolyamot egy fájlon, és elolvastuk a tartalmát. Ez összetett viselkedés, és hibákhoz vezethet.
Mi van, ha nem lenne ilyen fájl? Mi van, ha problémák adódtak a fájl olvasásával? Mi van, ha túl nagy volt?
Az összetett logika a hibák nagy valószínűségét jelenti, és ez azt jelenti, hogy a kódnak megfelelően kell kezelnie a kivételeket.
1. példa – Sorozatosítás
Egy szabványos Java programban rengeteg olyan helyzet adódik, amikor nem Ön hozza létre az osztályának objektumait. Tegyük fel például, hogy úgy dönt, hogy elküld egy objektumot a hálózaton keresztül: ebben az esetben a Java gép maga alakítja át az objektumot bájtok készletévé, elküldi, és újra létrehozza az objektumot a bájtkészletből.
De akkor tegyük fel, hogy a fájl nem létezik a másik számítógépen. Hiba lesz a konstruktorban, és senki sem fogja kezelni. És ez eléggé képes a program leállására.
2. példa – Egy osztály mezőinek inicializálása
Ha az osztálykonstruktor képes ellenőrzött kivételeket dobni, azaz a throws kulcsszóval van megjelölve, akkor a jelzett kivételeket meg kell fogni az objektumot létrehozó metódusban.
De mi van, ha nincs ilyen módszer? Példa:
Kód | jegyzet |
---|---|
|
Ez a kód nem fordítható le. |
Az FilePrinter
osztálykonstruktor képes ellenőrzött kivételt dobni , ami azt jelenti, hogy nem hozhat létre FilePrinter
objektumot anélkül, hogy azt egy try-catch blokkba nem csomagolná. Try-catch blokkot pedig csak metódusban lehet írni
5. Alaposztályú konstruktor
Az előző leckéken az öröklődésről beszéltünk egy kicsit. Sajnos az öröklődésről és az OOP-ról szóló teljes tárgyalásunk az OOP-nak szentelt szintre van fenntartva, és a konstruktorok öröklődése már számunkra is aktuális.
Ha az osztály egy másik osztályt örököl, a szülő osztály egy objektuma be lesz ágyazva az osztály egyik objektumába. Sőt, a szülő osztálynak saját változói és saját konstruktorai vannak.
Ez azt jelenti, hogy nagyon fontos, hogy ismerje és megértse a változók inicializálását és a konstruktorok meghívását, amikor az osztálynak van szülőosztálya, és annak változóit és metódusait örököljük.
osztályok
Honnan tudjuk a változók inicializálásának és a konstruktorok meghívásának sorrendjét? Kezdjük azzal, hogy megírjuk két osztály kódját. Az egyik örökli a másikat:
Kód | jegyzet |
---|---|
|
Az ChildClass osztály örökli az ParentClass osztályt. |
Meg kell határoznunk a változók inicializálásának és a konstruktorok meghívásának sorrendjét. A naplózás segít ebben.
Fakitermelés
A naplózás a program által futás közben végrehajtott műveletek rögzítésének folyamata úgy, hogy azokat a konzolra vagy egy fájlba írja.
Nagyon egyszerű megállapítani, hogy a konstruktort meghívták: a konstruktor törzsében írjon üzenetet a konzolnak. De hogyan lehet megállapítani, hogy egy változó inicializálva van-e?
Valójában ez sem túl nehéz: írjon egy speciális metódust, amely visszaadja a változó inicializálásához használt értéket, és naplózza az inicializálást. Így nézhet ki a kód:
Végső kód
|
ChildClass Objektum létrehozása Ez a metódus beírja az átadott szöveget a konzolba, és vissza is adja azt. Deklarálja a Display szöveg ParentClass osztályt , és inicializálja vele a változókat is. Írjon üzenetet, hogy meghívták a konstruktort. Figyelmen kívül hagyja a visszatérési értéket. Deklarálja a Display szöveg ChildClass osztályt , és inicializálja vele a változókat is. Írjon üzenetet, hogy meghívták a konstruktort. Figyelmen kívül hagyja a visszatérési értéket. |
Ha végrehajtja ezt a kódot, a képernyőn a következő szöveg jelenik meg:
A metódus konzol kimeneteMain.print() |
---|
|
Így mindig személyesen megbizonyosodhat arról, hogy egy osztály változói inicializálódnak a konstruktor meghívása előtt. Az alaposztály teljesen inicializálásra kerül az örökölt osztály inicializálása előtt.
GO TO FULL VERSION