שלום לכולם, היום אני ממשיך לנתח 250+ שאלות ראיונות עבור מפתח Java. חלקים קודמים של הניתוח: ראשון , שני , שלישי . אז בואו נמשיך.
<שם כיתה>{ירושה מכיתה אב} {יישום ממשק}
אז מה שיש לנו: {class access modifier} - רק המשתנים הציבוריים ומשנה הגישה החסר, כלומר ברירת המחדל, זמינים עבור המחלקה . {class static} - static הוא משנה המציין שהמחלקה הזו סטטית, מתאימה רק למחלקות פנימיות (מחלקות בתוך מחלקות אחרות). {class finality} - כזכור, זהו ה- final modifier , בנוכחותו המחלקה הופכת ללא תורשה (דוגמה מהתיבה - String ). {class abstraction} - modifier - abstract , מה שמציין שייתכן שיש למחלקה זו שיטות שלא יושמו. השינוי הזה מתנגש עם השינוי הסופי , כלומר, רק אחד מהם יכול להיות בכותרת המחלקה, שכן השינוי המופשט מרמז שהמחלקה הנתונה תעבור בירושה והחלקים המופשטים שלה ייושמו. וסופי מציין שזו הגרסה הסופית (הסופית) של המחלקה, והיא לא ניתנת בירושה . למעשה, השימוש בשני השינויים בו-זמנית יהיה אבסורדי, והמהדר לא יאפשר לנו לעשות זאת. <class> היא מילת מפתח נדרשת המציינת הצהרת מחלקה. <שם מחלקה> הוא שם מחלקה פשוט, שהוא המזהה של מחלקת Java ספציפית. שם הכיתה המלא מורכב משם החבילה המלאה + . + שם כיתה פשוט. {ירושה מכיתה אב} - ציון מחלקת האב (אם קיימת) באמצעות מילת המפתח extends . לדוגמה, .. מרחיב את ParentClass . {ממשק ממשק} - ציון הממשקים שמחלקה זו מיישמת (אם בכלל) באמצעות מילת המפתח implements . לדוגמה: ... מיישם את FirstInterface, SecondInterface ... ובכן, כדוגמה לכותרת מחלקה, קחו בחשבון את הכותרת של המחלקה Lion , שיורשת מ- Cat ומיישמת את ממשק WildAnimal :
29. האם ניתן להשתמש ב-retour בקונסטרוקטור?
אתה יכול, אבל בלי ערך ההחזרה מימין להחזרה . כלומר, אתה יכול להשתמש בהחזר; כקונסטרוקציה עזר במהלך חישובים בקונסטרוקטור על מנת לסיים (להפריע) בדחיפות את ביצוע הקוד הנוסף ולהשלים את האתחול של האובייקט. לדוגמא, יש לנו מחלקה Cat , ואם Cat הוא חסר בית - isHomeless = true , צריך לסיים את האתחול ולא למלא שדות אחרים (הרי הם לא ידועים לנו, היות והחתול חסר בית):public Cat(int age, String name, boolean isHomeless) {
if (isHomeless){
this.isHomeless = isHomeless;
return;
}
this.isHomeless = isHomeless;
this.age = age;
this.name = name;
}
אבל כשמדובר בערכים ספציפיים, בנאי לא יכול להשתמש ב-retour כדי להחזיר ערך מכיוון:
- כאשר מצהירים על בנאי לא יהיה לך משהו שדומה לסוג החזרה;
- בדרך כלל, הבנאי נקרא באופן מרומז במהלך המופע;
- בנאי אינו שיטה: זהו מנגנון נפרד שמטרתו היחידה היא לאתחל משתני מופע, והאופרטור החדש אחראי ליצירת אובייקט .
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 הוא שדה של שם האובייקט הוא ארגומנט מתודה. לא ניתן להשתמש בהפניה זו בשיטות סטטיות. 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";
}
הבלוק הזה זהה בדיוק לקודם. אבל אם הרגיל מופעל כאשר כל אובייקט מאותחל, אז הסטטי יופעל רק פעם אחת, כאשר המחלקה נטענת. בבלוק כזה, ככלל, כמה חישובים מורכבים מבוצעים גם לאתחול שלאחר מכן של משתני מחלקה סטטיים. אותן הגבלות חלות על בלוק סטטי כמו על שיטות סטטיות: הוא אינו יכול להשתמש בנתונים לא סטטיים, כמו גם בהתייחסות לאובייקט הנוכחי - זה . לאחר מכן, נוכל לראות את סדר האתחול של המחלקה (יחד עם האב הקדמון שלה) להבנה טובה יותר של הרגע שבו מופעלים בלוקי האתחול.
36. כדי לרשת מחלקה ציבורית בכיתה הילד מרחיב הורה, כתוב את סדר האתחול של האובייקט
כאשר הכיתה Child נטענת, סדר האתחול יהיה כדלקמן:- שדות סטטיים של כיתת הורים .
- בלוק אתחול סטטי עבור מחלקת האב .
- שדות סטטיים של כיתת הילד .
- בלוק אתחול סטטי עבור המחלקה Child .
- שדות לא סטטיים של כיתת האב .
- לא בלוק אתחול סטטי עבור מחלקת האב .
- קונסטרוקטור לכיתת הורים .
- שדות לא סטטיים של הכיתה Child .
- לא בלוק אתחול סטטי עבור המחלקה Child .
- בונה של כיתת הילד .
37. אילו יחסים אתה מכיר בין כיתות (אובייקטים)?
ישנם שני סוגים של קשרים בין מחלקות ב-Java:- מערכת יחסים IS-A
Lion IS-A Cat
(אבל לא כל חתול הוא אריה ) המצב הוא בדיוק אותו הדבר עם ממשקים. אם הכיתה Lion מיישמת את ממשק WildAnimal , אז הם גם נמצאים בקשר:
Lion IS-A WildAnimal
- HAS-A מערכות יחסים
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("Перевозка пассажира - " + 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