
new
و همه چیز آماده است :) در اینجا ما در مورد آنچه که در داخل کامپیوتر و ماشین جاوا هنگام نوشتن اتفاق می افتد صحبت خواهیم کرد، به عنوان مثال:
Cat cat = new Cat();
قبلاً در این مورد صحبت کردهایم، اما اگر به شما یادآوری کنیم:
- ابتدا حافظه برای ذخیره شی اختصاص داده می شود.
- سپس، ماشین جاوا یک مرجع به شی ایجاد می کند (در مورد ما مرجع Cat cat است).
- در نهایت، متغیرها مقداردهی اولیه می شوند و سازنده فراخوانی می شود (ما این فرآیند را با جزئیات بیشتری بررسی می کنیم).

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++;
}
}
کلاس Truck
پیاده سازی یک کامیون با فیلدهایی است که سال، مدل و حداکثر سرعت آن را نشان می دهد. اکنون می خواهیم یکی از این شی را ایجاد کنیم:
public class Main {
public static void main(String[] args) throws IOException {
Truck truck = new Truck(2017, "Scania S 500 4x2", 220);
}
}
برای ماشین جاوا، فرآیند به صورت زیر خواهد بود:
-
اولین چیزی که اتفاق می افتد این است که متغیرهای استاتیک کلاس
Vehicle
مقداردهی اولیه می شوند . بله گفتمVehicle
کلاس نهTruck
. متغیرهای استاتیک قبل از فراخوانی سازنده ها مقداردهی اولیه می شوند و این کار در کلاس والد شروع می شود. بیایید سعی کنیم این را تأیید کنیم.vehicleCounter
فیلدVehicle
کلاس را برابر با 10 قرار می دهیم و سعی می کنیم آن را در هر دو سازندهVehicle
و نمایش دهیمTruck
.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++; } }
ما عمداً عبارت println را در همان ابتدای سازنده قرار دادیم
Truck
تا مطمئن شویم که فیلدهای کامیون هنگامvehicleCounter
نمایش هنوز مقدار دهی اولیه نشده اند.و این هم نتیجه:
10 10
-
بعد از اینکه متغیرهای استاتیک کلاس والد مقداردهی اولیه شد، متغیرهای استاتیک کلاس فرزند مقداردهی اولیه می شوند. در مورد ما، این
truckCounter
زمینه کلاس استTruck
.بیایید آزمایش دیگری انجام دهیم که در آن سعی می کنیم قبل از مقداردهی اولیه فیلدهای دیگر، مقدار
truckCounter
داخل سازنده را نمایش دهیم:Truck
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++; } }
همانطور که می بینید، مقدار 10 قبلاً با شروع سازنده به متغیر استاتیک ما اختصاص داده شده است
Truck
. -
هنوز وقت سازندگان نرسیده است! مقداردهی اولیه متغیر ادامه دارد. متغیرهای غیراستاتیک کلاس والد در مرحله سوم مقداردهی اولیه می شوند. همانطور که می بینید، وراثت به طور قابل توجهی فرآیند ایجاد یک شی را پیچیده می کند، اما هیچ کاری نمی توانید در مورد آن انجام دهید: فقط باید برخی چیزها را در برنامه نویسی به خاطر بسپارید :)
به عنوان یک آزمایش، میتوانیم مقداری اولیه را به
description
متغیرVehicle
کلاس اختصاص دهیم و سپس آن را در سازنده تغییر دهیم.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; } }
بیایید
main()
روش خود را برای ایجاد یک کامیون اجرا کنیم:public class Main { public static void main(String[] args) throws IOException { Truck truck = new Truck(2017, "Scania S 500 4x2", 220); } }
نتیجه زیر را می گیریم:
Initial value of the description field Vehicle
این ثابت می کند که وقتی
Vehicle
سازنده شروع می شود بهdescription
فیلد قبلاً یک مقدار اختصاص داده شده است. -
بالاخره نوبت سازندگان می رسد! به طور دقیق تر، زمان سازنده کلاس پایه فرا رسیده است. در مرحله چهارم فرآیند ایجاد شیء فراخوانی می شود.
تأیید این موضوع نیز نسبتاً آسان است. بیایید خروجی دو خط را به کنسول امتحان کنیم: یکی در
Vehicle
سازنده کلاس پایه و دومی درTruck
سازنده.Vehicle
ما باید متقاعد شویم که ابتدا خط داخل نمایش داده می شود: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++; }
ما
main()
روش خود را اجرا می کنیم و به نتیجه نگاه می کنیم:Hello from the Vehicle constructor! Hello from the Truck constructor!
عالی یعنی ما اشتباه نمیکنیم :) بریم جلو.
-
حالا نوبت مقداردهی اولیه فیلدهای غیراستاتیک کلاس فرزند یعنی
Truck
کلاس ماست. فیلدهای بلافاصله داخل کلاس در حال نمونه سازی تا مرحله پنجم مقداردهی اولیه نمی شوند! شگفتآور است، اما درست است :) باز هم، ما یک بررسی ساده انجام میدهیم - درست مانند کلاس والد: مقداری اولیه برای متغیر تعیین میکنیمmaxSpeed
و درTruck
سازنده بررسی میکنیم که مقدار قبل از شروع سازنده اختصاص داده شده باشد: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++; } }
خروجی کنسول:
Initial value of maxSpeed = 150
همانطور که می بینید، زمانی که
Truck
سازنده شروع می شود،maxSpeed
در حال حاضر برابر با 150 است! -
سازنده
Truck
کلاس فرزند فراخوانی می شود.و تنها در این مرحله، آخر از همه، سازنده کلاسی که ما نمونه سازی می کنیم فراخوانی می شود!
فقط در مرحله ششم مقادیری که به عنوان آرگومان به کامیون خود ارسال می کنیم به فیلدها اختصاص داده می شود.
همانطور که می بینید، "ساخت" یک کامیون، یعنی فرآیند ایجاد شی، ساده نیست. اما به نظر می رسد که ما آن را به کوچکترین قسمت ها تقسیم کرده ایم :)

GO TO FULL VERSION