Elemezzük az elejétől a végéig: hogyan hívják meg a konstruktorokat, hogyan és milyen sorrendben inicializálják a mezőket (beleértve a statikus mezőket is) stb. Korábban már érintettünk néhány, a cikkben tárgyalt pontot, így áttekintheti az anyag az alaposztályú konstruktorokon . Először is emlékezzünk vissza egy objektum létrehozására. Jól emlékszel, hogyan néz ki ez a folyamat egy fejlesztő szemszögéből: létrehoz egy osztályt, ír new, és minden készen van :) Itt arról lesz szó, hogy mi történik például a számítógépen és a Java gépen belül, amikor írunk:
Cat cat = new Cat();
Korábban már beszéltünk erről, de hátha emlékeztetünk:
- Először az objektum tárolására szolgáló memória kerül lefoglalásra.
- Ezután a Java gép hivatkozást hoz létre az objektumra (esetünkben a hivatkozás Cat cat).
- Végül a változókat inicializáljuk, és meghívjuk a konstruktort (a folyamatot részletesebben megvizsgáljuk).
Ez az első két pont nem vethet fel különösebb kérdéseket. A memóriafoglalás egy egyszerű folyamat, és csak két lehetséges kimenetel van: vagy van memória, vagy nincs :) És a hivatkozás létrehozása nem szokatlan. A harmadik pont azonban szigorú sorrendben végrehajtott műveletek egész halmazát jelenti. Nem rajongok a tesztekkel való tolongásért, de jól kell értened ezt a folyamatot, és meg kell jegyezned ezt a műveletsort. Amikor az előző leckékben az objektumkészítés folyamatáról beszéltünk, még nem igazán tudtál semmit az öröklődésről, így néhány dolog elmagyarázása problémás volt. Most már elég sok mindent tudsz, és végre teljes egészében megfontolhatjuk ezt a kérdést :) Tehát a harmadik pont azt mondja: " Végül inicializálódnak a változók és meghívják a konstruktort. " De milyen sorrendben történik mindez? A jobb megértés érdekében hozzunk létre két szuper egyszerű osztályt – egy szülőt és egy gyereket:
public class Vehicle {
public static int vehicleCounter = 0;
private String description = "Vehicle";
public Vehicle() {
}
public String getDescription() {
return description;
}
}
public class Truck extends Vehicle {
private static int truckCounter = 0;
private int yearOfManufacture;
private String model;
private int maxSpeed;
public Truck(int yearOfManufacture, String model, int maxSpeed) {
this.yearOfManufacture = yearOfManufacture;
this.model = model;
this.maxSpeed = maxSpeed;
Vehicle.vehicleCounter++;
truckCounter++;
}
}
Az Truckosztály egy teherautó megvalósítása, amelynek mezői jelzik az évszámot, a modellt és a maximális sebességet. Most egy ilyen objektumot szeretnénk létrehozni:
public class Main {
public static void main(String[] args) throws IOException {
Truck truck = new Truck(2017, "Scania S 500 4x2", 220);
}
}
A Java gépen a folyamat így fog kinézni:
-
Az első dolog, ami történik, az osztály statikus változói
Vehicleinicializálódnak . Igen, mondtam azVehicleosztálynak, nemTruck. A statikus változók inicializálása a konstruktorok meghívása előtt történik, és ez a szülőosztályban kezdődik. Próbáljuk meg ezt ellenőrizni.vehicleCounterAz osztály mezőjét 10-re állítjukVehicle, és megpróbáljuk megjeleníteni mind a,VehiclemindTrucka konstruktorban.public class Vehicle { public static int vehicleCounter = 10; private String description = "Vehicle"; public Vehicle() { System.out.println(vehicleCounter); } public String getDescription() { return description; } } public class Truck extends Vehicle { private static int truckCount = 0; private int yearOfManufacture; private String model; private int maxSpeed; public Truck(int yearOfManufacture, String model, int maxSpeed) { System.out.println(vehicleCounter); this.yearOfManufacture = yearOfManufacture; this.model = model; this.maxSpeed = maxSpeed; Vehicle.vehicleCounter++; truckCount++; } }Szándékosan elhelyeztük a println utasítást a konstruktor legelejére,
Truckhogy megbizonyosodjunk arról, hogy a teherautó mezői még nincsenek inicializálva, amikorvehicleCountermegjelenik.És íme az eredmény:
10 10 -
A szülőosztály statikus változóinak inicializálása után a gyermekosztály statikus változói inicializálódnak. Esetünkben ez
truckCounteraz osztály terepeTruck.Végezzünk el egy másik kísérletet, ahol megpróbáljuk megjeleníteni
truckCounteraTruckkonstruktoron belüli értékét, mielőtt a többi mezőt inicializálnánk:public class Truck extends Vehicle { private static int truckCounter = 10; private int yearOfManufacture; private String model; private int maxSpeed; public Truck(int yearOfManufacture, String model, int maxSpeed) { System.out.println(truckCounter); this.yearOfManufacture = yearOfManufacture; this.model = model; this.maxSpeed = maxSpeed; Vehicle.vehicleCounter++; truckCounter++; } }Amint látja, a 10-es érték már hozzá van rendelve a statikus változónkhoz, amikor a
Truckkonstruktor elindul. -
Még mindig nincs itt az ideje a kivitelezőknek! A változó inicializálása folytatódik. A szülőosztály nem statikus változói harmadikként inicializálódnak. Mint látható, az öröklődés jelentősen megnehezíti az objektum létrehozásának folyamatát, de ez ellen nem tudsz mit tenni: csak meg kell jegyezned néhány dolgot a programozás során :)
Kísérletként az osztályban hozzárendelhetünk valamilyen kezdeti értéket a változóhoz
description,Vehiclemajd a konstruktorban megváltoztathatjuk.public class Vehicle { public static int vehicleCounter = 10; private String description = "Initial value of the description field"; public Vehicle() { System.out.println(description); description = "Vehicle"; System.out.println(description); } public String getDescription() { return description; } }Futtassuk le
main()a módszerünket, amely teherautót hoz létre:public class Main { public static void main(String[] args) throws IOException { Truck truck = new Truck(2017, "Scania S 500 4x2", 220); } }A következő eredményt kapjuk:
Initial value of the description field VehicleEz bizonyítja, hogy amikor a
Vehiclekonstruktor elindul, adescriptionmezőhöz már hozzá van rendelve egy érték. -
Végre eljött a kivitelezők ideje! Pontosabban, itt az ideje az alaposztály-konstruktornak. Az objektum létrehozási folyamat negyedik lépésében hívódik meg.
Ezt is meglehetősen könnyű ellenőrizni. Próbáljunk meg két sort kiírni a konzolra: az egyiket az
Vehiclealaposztály-konstruktoron belül, a másodikat aTruckkonstruktoron belül. Meg kell győződnünk arról, hogyVehicleelőször a belső sor jelenik meg:public Vehicle() { System.out.println("Hello from the Vehicle constructor!"); } public Truck(int yearOfManufacture, String model, int maxSpeed) { System.out.println("Hello from the Truck constructor!"); this.yearOfManufacture = yearOfManufacture; this.model = model; this.maxSpeed = maxSpeed; Vehicle.vehicleCounter++; truckCounter++; }Futtatjuk a módszerünket
main(), és megnézzük az eredményt:Hello from the Vehicle constructor! Hello from the Truck constructor!Kiváló. Ez azt jelenti, hogy nem tévedünk :) Menjünk tovább.
-
Itt az ideje a gyermekosztály, azaz a mi osztályunk nem statikus mezőinek inicializálásának
Truck. A közvetlenül példányosított osztályon belüli mezők csak az ötödik lépésben inicializálódnak! Meglepő, de igaz :) Ismét végzünk egy egyszerű ellenőrzést – csakúgy, mint a szülőosztálynál: a változó kezdeti értékét adjuk,maxSpeedés a konstruktorbanTruckellenőrizzük, hogy az érték a konstruktor elindulása előtt lett-e hozzárendelve:public class Truck extends Vehicle { private static int truckCounter = 10; private int yearOfManufacture; private String model; private int maxSpeed = 150; public Truck(int yearOfManufacture, String model, int maxSpeed) { System.out.println("Initial value of maxSpeed = " + this.maxSpeed); this.yearOfManufacture = yearOfManufacture; this.model = model; this.maxSpeed = maxSpeed; Vehicle.vehicleCounter++; truckCounter++; } }Konzol kimenet:
Initial value of maxSpeed = 150Mint látható, amikor a
Truckkonstruktor elindul,maxSpeedmár egyenlő 150-nel! -
A
Truckgyermekosztály konstruktorát ún.És végül csak ezen a ponton hívják meg annak az osztálynak a konstruktorát, amelyet példányosítunk!
Csak a hatodik lépésben lesznek a mezők hozzárendelve azok az értékek, amelyeket argumentumként adunk át a teherautónak.
Amint látja, egy teherautó „megépítése”, vagyis az objektum létrehozási folyamata nem egyszerű. De úgy tűnik, a legapróbb részekre bontottuk :)
Miért olyan fontos ezt a folyamatot jól megérteni? Képzeld el, milyen váratlan lehet egy közönséges tárgy létrehozásának eredménye, ha nem tudnád pontosan, mi történik "a motorháztető alatt" :) Most itt az ideje, hogy visszatérj a kurzushoz és teljesíts néhány feladatot! Sok sikert és hamarosan találkozunk! :)
GO TO FULL VERSION