
new
și totul este gata :) Aici vom vorbi despre ce se întâmplă în interiorul computerului și a mașinii Java când scriem, de exemplu:
Cat cat = new Cat();
Am mai vorbit despre asta, dar în caz că vă reamintim:
- În primul rând, este alocată memoria pentru stocarea obiectului.
- Apoi, mașina Java creează o referință la obiect (în cazul nostru referința este Cat cat).
- În cele din urmă, variabilele sunt inițializate și constructorul este apelat (vom analiza acest proces mai detaliat).

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++;
}
}
Clasa Truck
este o implementare a unui camion cu câmpuri care reprezintă anul, modelul și viteza maximă. Acum vrem să creăm un astfel de obiect:
public class Main {
public static void main(String[] args) throws IOException {
Truck truck = new Truck(2017, "Scania S 500 4x2", 220);
}
}
Pentru mașina Java, procesul va arăta astfel:
-
Primul lucru care se întâmplă este că variabilele statice ale
Vehicle
clasei sunt inițializate . Da, am spusVehicle
clasa, nuTruck
. Variabilele statice sunt inițializate înainte ca constructorii să fie apelați, iar aceasta începe în clasa părinte. Să încercăm să verificăm acest lucru. SetămvehicleCounter
câmpul dinVehicle
clasă egal cu 10 și încercăm să îl afișam atât în constructori,Vehicle
cât șiTruck
în constructori.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++; } }
Am pus în mod deliberat instrucțiunea println chiar la începutul constructorului
Truck
pentru a ne asigura că câmpurile camionului nu au fost încă inițializate cândvehicleCounter
este afișată.Și iată rezultatul:
10 10
-
După ce variabilele statice ale clasei părinte sunt inițializate, variabilele statice ale clasei fii sunt inițializate. În cazul nostru, acesta este
truckCounter
domeniul claseiTruck
.Să facem un alt experiment în care vom încerca să afișăm valoarea din
truckCounter
interiorulTruck
constructorului înainte ca celelalte câmpuri să fie inițializate: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++; } }
După cum puteți vedea, valoarea 10 a fost deja atribuită variabilei noastre statice când
Truck
începe constructorul. -
Inca nu este timpul pentru constructori! Inițializarea variabilei continuă. Variabilele non-statice ale clasei părinte sunt inițializate al treilea. După cum puteți vedea, moștenirea complică semnificativ procesul de creare a unui obiect, dar nu puteți face nimic în acest sens: trebuie doar să memorați câteva lucruri în programare :)
Ca experiment, putem atribui o valoare inițială variabilei
description
dinVehicle
clasă și apoi o putem schimba în 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; } }
Să rulăm
main()
metoda noastră care creează un camion:public class Main { public static void main(String[] args) throws IOException { Truck truck = new Truck(2017, "Scania S 500 4x2", 220); } }
Obtinem urmatorul rezultat:
Initial value of the description field Vehicle
Acest lucru demonstrează că atunci când
Vehicle
constructorul începedescription
câmpul i s-a atribuit deja o valoare. -
În sfârșit, este timpul pentru constructori! Mai precis, este timpul pentru constructorul clasei de bază. Este invocat în a patra etapă a procesului de creare a obiectului.
Acest lucru este, de asemenea, destul de ușor de verificat. Să încercăm să scoatem două linii în consolă: una în
Vehicle
constructorul clasei de bază, a doua în interiorulTruck
constructorului. Trebuie să fim convinși că linia din interiorVehicle
este afișată mai întâi: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++; }
Vom rula
main()
metoda noastră și ne vom uita la rezultat:Hello from the Vehicle constructor! Hello from the Truck constructor!
Excelent. Asta înseamnă că nu ne înșelim :) Să mergem mai departe.
-
Acum este timpul pentru inițializarea câmpurilor non-statice ale clasei copil, adică
Truck
clasa noastră. Câmpurile imediat din clasa instanțiată nu sunt inițializate până la pasul al cincilea! Surprinzător, dar adevărat :) Din nou, vom face o verificare simplă - la fel ca în cazul clasei părinte: vom da o valoare inițială variabileimaxSpeed
și înTruck
constructor vom verifica dacă valoarea a fost atribuită înainte de a începe constructorul: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++; } }
Ieșire din consolă:
Initial value of maxSpeed = 150
După cum puteți vedea, când
Truck
pornește constructorul,maxSpeed
este deja egal cu 150! -
Constructorul
Truck
clasei copil este numit.Și numai în acest moment, în sfârșit, va fi numit constructorul clasei pe care o instanțiem!
Numai în pasul al șaselea câmpurilor li se vor atribui valorile pe care le transmitem ca argumente camionului nostru.
După cum puteți vedea, „construirea” unui camion, adică procesul de creare a obiectelor, nu este simplă. Dar se pare că l-am împărțit în cele mai mici părți :)

GO TO FULL VERSION