
new
, en alles is klaar :) Hier zullen we het hebben over wat er in de computer en de Java-machine gebeurt als we schrijven, bijvoorbeeld:
Cat cat = new Cat();
We hebben hier eerder over gesproken, maar voor het geval we u eraan herinneren:
- Eerst wordt geheugen voor het opslaan van het object toegewezen.
- Vervolgens maakt de Java-machine een verwijzing naar het object (in ons geval is de verwijzing Cat cat).
- Ten slotte worden variabelen geïnitialiseerd en wordt de constructor aangeroepen (we gaan dit proces in meer detail bekijken).

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++;
}
}
De Truck
klasse is een implementatie van een vrachtwagen met velden die het jaar, het model en de maximale snelheid vertegenwoordigen. Nu willen we zo'n object maken:
public class Main {
public static void main(String[] args) throws IOException {
Truck truck = new Truck(2017, "Scania S 500 4x2", 220);
}
}
Voor de Java-machine ziet het proces er als volgt uit:
-
Het eerste dat gebeurt, is dat de statische variabelen van de
Vehicle
klasse worden geïnitialiseerd . Ja, ik zei deVehicle
klas, nietTruck
. Statische variabelen worden geïnitialiseerd voordat constructors worden aangeroepen, en dit begint in de bovenliggende klasse. Laten we proberen dit te verifiëren. We stellen hetvehicleCounter
veld in deVehicle
klasse gelijk aan 10 en proberen het weer te geven in zowel deVehicle
enTruck
constructors.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++; } }
We hebben de instructie println met opzet helemaal aan het begin van de
Truck
constructor geplaatst om er zeker van te zijn dat de velden van de vrachtwagen nog niet zijn geïnitialiseerd wanneervehicleCounter
wordt weergegeven.En hier is het resultaat:
10 10
-
Nadat de statische variabelen van de bovenliggende klasse zijn geïnitialiseerd, worden de statische variabelen van de onderliggende klasse geïnitialiseerd. In ons geval is dit het
truckCounter
veld van deTruck
klasse.Laten we nog een experiment doen waarbij we proberen de waarde van
truckCounter
binnen deTruck
constructor weer te geven voordat de andere velden worden geïnitialiseerd: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++; } }
Zoals u kunt zien, is de waarde 10 al toegewezen aan onze statische variabele wanneer de
Truck
constructor begint. -
Het is nog steeds geen tijd voor de constructeurs! Variabele initialisatie gaat door. De niet-statische variabelen van de bovenliggende klasse worden als derde geïnitialiseerd. Zoals je kunt zien, bemoeilijkt overerving het proces van het maken van een object aanzienlijk, maar je kunt er niets aan doen: je moet gewoon een aantal dingen onthouden tijdens het programmeren :)
Bij wijze van experiment kunnen we een beginwaarde toekennen aan de
description
variabele inVehicle
class en deze vervolgens wijzigen in de constructor.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; } }
Laten we onze
main()
methode uitvoeren die een vrachtwagen maakt:public class Main { public static void main(String[] args) throws IOException { Truck truck = new Truck(2017, "Scania S 500 4x2", 220); } }
We krijgen het volgende resultaat:
Initial value of the description field Vehicle
Dit bewijst dat wanneer de
Vehicle
constructor begint, hetdescription
veld al een waarde heeft gekregen. -
Eindelijk is het tijd voor de constructeurs! Om precies te zijn, het is tijd voor de constructor van de basisklasse. Het wordt aangeroepen in de vierde stap van het objectcreatieproces.
Dit is ook vrij eenvoudig te verifiëren. Laten we proberen twee regels naar de console uit te voeren: één binnen de
Vehicle
constructor van de basisklasse, de tweede binnen deTruck
constructor. We moeten ervan overtuigd zijn dat de regel binneninVehicle
als eerste wordt weergegeven: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++; }
We zullen onze
main()
methode uitvoeren en naar het resultaat kijken:Hello from the Vehicle constructor! Hello from the Truck constructor!
Uitstekend. Dat betekent dat we ons niet vergissen :) Laten we verder gaan.
-
Nu is het tijd voor initialisatie van de niet-statische velden van de onderliggende klasse, dwz onze
Truck
klasse. De velden direct binnen de klasse die wordt geïnstantieerd, worden pas in de vijfde stap geïnitialiseerd! Verrassend, maar waar :) Nogmaals, we zullen een eenvoudige controle uitvoeren — net als bij de ouderklasse: we geven een beginwaarde aan demaxSpeed
variabele en in deTruck
constructor controleren we of de waarde was toegewezen voordat de constructor startte: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++; } }
Console-uitvoer:
Initial value of maxSpeed = 150
Zoals u kunt zien, is wanneer de
Truck
constructor startmaxSpeed
al gelijk aan 150! -
De constructor van de
Truck
onderliggende klasse wordt aangeroepen.En pas op dit punt, als laatste, zal de constructor van de klasse die we instantiëren worden aangeroepen!
Pas in de zesde stap krijgen de velden de waarden toegewezen die we als argumenten doorgeven aan onze vrachtwagen.
Zoals u kunt zien, is het "construeren" van een vrachtwagen, dwz het maken van objecten, niet eenvoudig. Maar het lijkt erop dat we het in de kleinste delen hebben opgesplitst :)

GO TO FULL VERSION