سلام، همه! امروز به بررسی سوالات مصاحبه توسعه دهندگان جاوا ادامه می دهم.
اکنون میتوانیم به ترتیب اولیهسازی کلاس (همراه با کلاس والد آن) نگاه کنیم تا درک بهتری داشته باشیم که دقیقاً چه زمانی بلوکهای اولیه فراخوانی شدهاند.

29. آیا می توان از بازگشت در یک سازنده استفاده کرد؟
بله، اما فقط بدون مقدار در سمت راست کلمه کلیدی بازگشتی . می توانید از بازگشت استفاده کنید. به عنوان یک دستور کمکی در سازنده برای خاتمه فوری (وقفه) اجرای کد بیشتر و پایان دادن به مقداردهی اولیه شی. به عنوان مثال، فرض کنید ما یک کلاس Cat داریم ، و اگر یک Cat بیخانمان باشد ( isHomeless = درست است ، پس میخواهیم مقداردهی اولیه را خاتمه دهیم و فیلدهای دیگر را پر نکنیم (در نهایت، آنها برای ما ناشناخته هستند، زیرا گربه بیخانمان است) :public Cat(int age, String name, boolean isHomeless) {
if (isHomeless){
this.isHomeless = isHomeless;
return;
}
this.isHomeless = isHomeless;
this.age = age;
this.name = name;
}
اما اگر در مورد مقادیر مشخص صحبت می کنیم، کلمه کلیدی بازگشت نمی تواند مقدار خاصی را برگرداند زیرا:
- وقتی سازنده ای را اعلام می کنید، چیزی شبیه نوع بازگشتی نخواهید داشت.
- به عنوان یک قاعده، سازنده به طور ضمنی در هنگام نمونه سازی فراخوانی می شود.
- سازنده یک متد نیست: یک مکانیسم جداگانه است که تنها هدف آن مقداردهی اولیه متغیرهای نمونه است، به عنوان مثال، ما از عملگر جدید برای ایجاد یک شی استفاده می کنیم.

30. آیا می توان از سازنده یک استثنا انداخت؟
سازندگان با استثناها به همان روشی کار می کنند که متدها انجام می دهند. متدها به ما این امکان را می دهند که با نوشتن پرتاب <ExceptionType> در هدر متد، استثناها را پرتاب کنیم. و سازنده ها به ما اجازه می دهند همین کار را انجام دهیم. وقتی سازنده یک کلاس فرزند را به ارث می بریم و تعریف می کنیم، می توانیم نوع استثنا را گسترش دهیم - برای مثال، IOException -> Exception (اما نه برعکس). بیایید سازنده کلاس Cat را به عنوان مثالی از سازنده ای که یک استثنا پرتاب می کند استفاده کنیم. فرض کنید وقتی یک شی را ایجاد می کنیم، می خواهیم نام و سن را از کنسول وارد کنیم:public Cat() throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
this.name = reader.readLine();
this.age = Integer.parseInt(reader.readLine());
}
از آنجایی که reader.readLine() یک IOException می اندازد، آن را در هدر به عنوان یک استثنای احتمالی می نویسیم.
31. عناصر سربرگ کلاس چیست؟ یک مثال بنویسید
برای نشان دادن عناصری که یک هدر کلاس را تشکیل می دهند، اجازه دهید به یک طرحواره کوچک نگاه کنیم:- عناصر اجباری در پرانتز <> ظاهر می شوند
- عناصر اختیاری در {} هستند
public final class Lion extends Cat implements WildAnimal

32. عناصر هدر متد چیست؟ یک مثال بنویسید
هنگام در نظر گرفتن عناصر تشکیل دهنده یک هدر متد، اجازه دهید دوباره یک طرح کوچک را در نظر بگیریم:- عناصر اجباری در پرانتز <> ظاهر می شوند
- عناصر اختیاری در {} هستند
public static void main(String[] args) throws IOException
33. یک سازنده پیش فرض در کلاس فرزند ایجاد کنید اگر قبلاً در کلاس پایه تعریف نشده است (اما سازنده دیگری تعریف شده است)
من مطمئن نیستم که سؤال را کاملاً درک کرده باشم، اما شاید به این معنی است که ما سازنده ای مانند این در کلاس والد داریم:public Cat(int age, String name) {
this.age = age;
this.name = name;
}
در این صورت، در کلاس والد، قطعاً باید سازنده ای تعریف کنیم که والد را مقداردهی اولیه کند (یعنی سازنده والد را فراخوانی کند):
public class Lion extends Cat {
public Lion(int age, String name) {
super(age, name);
}
}

34. چه زمانی از این کلمه کلیدی استفاده می شود؟
در جاوا این دو معنی متفاوت دارد. 1. ارجاع به شی فعلی است، به عنوان مثال this.age = 9 . یعنی این به شیئی که در آن استفاده شده و کد با این به آن اشاره دارد اشاره دارد. هدف اصلی بهبود خوانایی کد و جلوگیری از ابهام است. به عنوان مثال، اگر یک فیلد نمونه و یک آرگومان متد یک نام داشته باشند:public void setName(String name) {
this.name = name;
}
یعنی this.name فیلد شی است، در حالی که name پارامتر متد است. این مرجع را نمی توان در روش های استاتیک استفاده کرد. 2. در سازنده، این را می توان مانند یک متد نامید، به عنوان مثال this(value) . در این صورت فراخوانی به سازنده دیگری از همان کلاس خواهد بود. اساساً میتوانید در طول فرآیند ایجاد یک شی، دو سازنده را فراخوانی کنید:
public Cat(int age, String name) {
this(name);
this.age = age;
}
public Cat(String name) {
this.name = name;
}
هنگام فراخوانی اولین سازنده برای ایجاد یک شی Cat ، هر دو فیلد نمونه با موفقیت مقداردهی اولیه می شوند. در اینجا چند تفاوت وجود دارد:
- this() فقط در یک سازنده کار می کند.
- ارجاع به سازنده دیگری باید در خط اول بلوک سازنده (بدنه) باشد. این بدان معناست که یک سازنده نمی تواند بیش از یک سازنده (سایر) کلاس خود را فراخوانی کند.

35. مقداردهی اولیه چیست؟
تا جایی که من متوجه شدم، این سوال در مورد بلوک های اولیه و استاتیک اولیه است. بیایید ابتدا به یاد بیاوریم که مقداردهی اولیه چیست. اولیه سازی ایجاد، فعال سازی، آماده سازی و تعریف فیلدها است. آماده سازی یک برنامه یا جزء برای آماده شدن برای استفاده. به یاد می آورید که وقتی یک شی را ایجاد می کنید، یک متغیر کلاس می تواند بلافاصله پس از اعلان مقداردهی اولیه شود:class Cat {
private int age = 9;
private String name = "Tom";
یا بعد از واقعیت از طریق سازنده تنظیم کنید:
class Cat {
private int age;
private String name;
public Cat(int age, String name) {
this.age = age;
this.name = name;
}
اما راه دیگری وجود دارد: می توانید یک متغیر نمونه را با استفاده از یک بلوک اولیه تنظیم کنید، که به شکل پرانتزهای مجعد {} در داخل یک کلاس، بدون نام (مانند یک متد یا سازنده بی نام) تنظیم می شود:
class Cat {
private int age;
private String name;
{
age = 10;
name = "Tom";
}
بلوک مقداردهی اولیه قطعه ای از کد است که هنگام ایجاد یک شی بارگذاری می شود. چنین بلوکهایی معمولاً برای انجام محاسبات پیچیده خاصی استفاده میشوند که هنگام بارگذاری یک کلاس مورد نیاز است. نتایج این محاسبات را می توان به عنوان مقادیر متغیرها تنظیم کرد. علاوه بر بلوک های اولیه اولیه، بلوک های ثابت نیز وجود دارد. آنها یکسان به نظر می رسند اما کلمه کلیدی ثابت را در جلوی بند باز می کنند:
class Cat {
private static int age;
private static String name;
static{
age = 10;
name = "Tom";
}
این بلوک مانند بلوک قبلی است. اما اگر حالت معمولی زمانی اجرا شود که هر شیء مقدار دهی اولیه می شود، آنگاه استاتیک تنها یک بار، زمانی که کلاس بارگذاری می شود، اجرا می شود. به عنوان یک قاعده، محاسبات پیچیده خاصی در یک بلوک استاتیک انجام می شود که برای مقداردهی اولیه متغیرهای کلاس ایستا استفاده می شود. همان محدودیتها برای یک بلوک استاتیک که برای روشهای استاتیک اعمال میشود اعمال میشود: شما نمیتوانید از دادههای غیراستاتیک، مانند ارجاع به شی فعلی ( this ) در یک بلوک استاتیک استفاده کنید. 
36. با توجه به یک کلاس Child عمومی که Parent را گسترش می دهد، ترتیب اولیه شی را بنویسید
هنگام بارگذاری کلاس Child ، ترتیب اولیه سازی به صورت زیر خواهد بود:- فیلدهای کلاس ایستا از کلاس Parent .
- بلوک اولیه سازی استاتیک کلاس Parent .
- فیلدهای ثابت کلاس Сhild .
- بلوک اولیه سازی استاتیک کلاس Child .
- فیلدهای غیر استاتیک از کلاس Parent .
- بلوک مقداردهی اولیه غیراستاتیک کلاس Parent .
- سازنده کلاس والد .
- فیلدهای غیر استاتیک از کلاس Сhild .
- بلوک مقداردهی اولیه غیراستاتیک کلاس Сhild .
- سازنده کلاس Сhild .

37. چه نوع روابط بین کلاس ها (اشیاء) را می شناسید؟
دو نوع متغیر در جاوا وجود دارد: انواع اولیه و ارجاع به اشیاء کامل.- روابط IS-A
Lion IS-A Cat
(اما هر گربه شیر نیست ) همین وضعیت در رابط ها وجود دارد. اگر کلاس Lion واسط WildAnimal را پیاده سازی کند ، در این رابطه نیز وجود دارد:
Lion IS-A WildAnimal
- رابطه دارد
Car HAS-A Passenger
و بالعکس: اگر مسافر اشاره ای به خودرو داشته باشد ، این رابطه خواهد بود:
Passenger HAS-A Car
38. چه روابط شیء انجمنی را می شناسید؟
تجمیع و ترکیب چیزی جز موارد خاص تداعی نیست. تجمع رابطه ای است که در آن یک شی بخشی از شی دیگر است. به عنوان مثال، یک مسافر ممکن است در یک ماشین قرار داشته باشد. علاوه بر این، ممکن است چندین مسافر وجود داشته باشد یا اصلاً هیچ مسافری وجود نداشته باشد (و اگر در مورد تسلا صحبت می کنیم، ممکن است هیچ راننده ای وجود نداشته باشد). مثلا:public class Car {
private List passengers = new ArrayList<>();
void setPassenger(Passenger passenger) {
passengers.add(passenger);
}
void move() {
for (Passenger passenger : passengers) {
System.out.println("Transporting passenger - " + passenger.toString());
}
passengers.clear();
}
}
به عبارت دیگر، تعداد مسافران (در هر کدام) برای ما مهم نیست: عملکرد کلاس خودرو به این بستگی ندارد. تجمیع همچنین به این معنی است که وقتی شی دیگری از یک شی استفاده می کند، اولین شی می تواند توسط اشیاء دیگر استفاده شود. به عنوان مثال، ممکن است همان دانش آموز هم در یک باشگاه بافتنی و هم در یک گروه راک باشد و همزمان در کلاس اسپانیایی شرکت کند. همانطور که میتوانید تصور کنید، تجمیع یک رابطه تداعی ضعیفتر بین طبقات است. ترکیب یک رابطه حتی تنگ تر است که در آن یک شی نه تنها بخشی از یک شی دیگر است، بلکه کار یک شی بسیار به دیگری وابسته است. مثلا ماشینی موتور دارد. یک موتور ممکن است بدون ماشین وجود داشته باشد، اما در خارج از ماشین بی فایده است. و یک ماشین بدون موتور نمی تواند کار کند:
public class Car {
private Engine engine;
public Car(Engine engine) {
this.engine = engine;
}
void startMoving() {
engine.start();
...
}
ترکیب همچنین به این معنی است که وقتی شی دیگری از یک شی استفاده می کند، اولین شی نمی تواند به هیچ شی دیگری تعلق داشته باشد. به مثال ما برگردیم، یک موتور فقط می تواند متعلق به یک خودرو باشد، نه دو یا چند خودرو همزمان. من فکر می کنم برای امروز کافی است، بنابراین ما در اینجا توقف می کنیم.
GO TO FULL VERSION