
new
, og alt er klar :) Her vil vi tale om, hvad der sker inde i computeren og Java-maskinen, når vi skriver, for eksempel:
Cat cat = new Cat();
Vi har talt om dette før, men bare hvis vi skal minde dig om:
- Først tildeles hukommelse til lagring af objektet.
- Dernæst opretter Java-maskinen en reference til objektet (i vores tilfælde er referencen Cat cat).
- Til sidst initialiseres variabler, og konstruktøren kaldes (vi skal se på denne proces mere detaljeret).

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++;
}
}
Klassen Truck
er en implementering af en lastbil med felter, der repræsenterer dens årgang, model og maksimale hastighed. Nu vil vi oprette et sådant objekt:
public class Main {
public static void main(String[] args) throws IOException {
Truck truck = new Truck(2017, "Scania S 500 4x2", 220);
}
}
For Java-maskinen vil processen se sådan ud:
-
Det første, der sker, er, at klassens statiske variable
Vehicle
initialiseres . Ja, jeg sagdeVehicle
klassen, ikkeTruck
. Statiske variable initialiseres før konstruktører kaldes, og dette starter i den overordnede klasse. Lad os prøve at bekræfte dette. Vi sættervehicleCounter
feltet iVehicle
klassen lig med 10 og forsøger at vise det i både konstruktørerneVehicle
ogTruck
.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++; } }
Vi satte bevidst println-sætningen helt i begyndelsen af konstruktøren
Truck
for at være sikker på, at lastbilens felter endnu ikke er blevet initialiseret, nårvehicleCounter
den vises.Og her er resultatet:
10 10
-
Efter at de statiske variabler for den overordnede klasse er initialiseret, initialiseres de statiske variabler for den underordnede klasse. I vores tilfælde er dette
truckCounter
klassens feltTruck
.Lad os lave endnu et eksperiment, hvor vi prøver at vise værdien af
truckCounter
inde iTruck
konstruktøren, før de andre felter initialiseres: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++; } }
Som du kan se, er værdien 10 allerede blevet tildelt vores statiske variabel, når
Truck
konstruktøren begynder. -
Det er stadig ikke tid til konstruktørerne! Variabel initialisering fortsætter. De ikke-statiske variable i den overordnede klasse initialiseres som tredje. Som du kan se, komplicerer arv betydeligt processen med at skabe et objekt, men der er intet du kan gøre ved det: Du skal bare huske nogle ting i programmering :)
Som et eksperiment kan vi tildele en begyndelsesværdi til variablen
description
iVehicle
klassen og derefter ændre den i konstruktøren.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; } }
Lad os køre vores
main()
metode, der skaber en lastbil:public class Main { public static void main(String[] args) throws IOException { Truck truck = new Truck(2017, "Scania S 500 4x2", 220); } }
Vi får følgende resultat:
Initial value of the description field Vehicle
Dette beviser, at når
Vehicle
konstruktøren begynder,description
er feltet allerede blevet tildelt en værdi. -
Endelig er det tid til konstruktørerne! Mere præcist er det tid til basisklassekonstruktøren. Det påberåbes i det fjerde trin af objektoprettelsesprocessen.
Dette er også ret nemt at verificere. Lad os prøve at udlæse to linjer til konsollen: en inde i basisklassekonstruktøren
Vehicle
, den anden inde iTruck
konstruktøren. Vi skal være overbevist om, at linjen indeniVehicle
vises først: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++; }
Vi kører vores
main()
metode og ser på resultatet:Hello from the Vehicle constructor! Hello from the Truck constructor!
Fremragende. Det betyder, at vi ikke tager fejl :) Lad os komme videre.
-
Nu er det tid til initialisering af de ikke-statiske felter i børneklassen, altså vores
Truck
klasse. Felterne umiddelbart inden for den klasse, der instantieres, initialiseres ikke før det femte trin! Overraskende, men sandt :) Igen laver vi et simpelt tjek — ligesom med den overordnede klasse: vi indlæser en startværdi til variablen,maxSpeed
og iTruck
konstruktøren tjekker vi, at værdien blev tildelt, før konstruktøren startede: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++; } }
Konsoludgang:
Initial value of maxSpeed = 150
Som du kan se, når
Truck
konstruktøren starter,maxSpeed
er det allerede lig med 150! -
Konstruktøren af
Truck
børneklassen kaldes.Og først på dette tidspunkt, sidst af alt, vil konstruktøren af den klasse, vi instansierer, blive kaldt!
Først i det sjette trin vil felterne blive tildelt de værdier, som vi sender som argumenter til vores lastbil.
Som du kan se, er det ikke nemt at "konstruere" en lastbil, dvs. processen med at skabe objekter. Men det ser ud til, at vi har delt det op i de mindste dele :)

GO TO FULL VERSION