היי! אנו ממשיכים לחקור את הנושא של מחלקות מקוננות בג'אווה. בתרגיל האחרון דיברנו על מחלקות מקוננות לא סטטיות, המוכרות גם כשיעורים פנימיים.
היום אנחנו עוברים לקבוצה אחרת של שיעורים. נשקול מחלקות מקוננות סטטיות.
במה הם שונים משיעורים אחרים? כאשר מכריזים על סוג זה של מחלקה, אנו משתמשים במילת המפתח הסטטית, שאתה כבר מכיר:
בדוגמה זו, יש לנו את
כפי שאמרנו בשיעור האחרון, יצירת מחלקה מקוננת כזו משפרת את האנקפסולציה ותורמת להפשטה מציאותית יותר. מה ההבדל בין מחלקות מקוננות סטטיות ולא סטטיות? 1. אובייקט של


public class Boeing737 {
private int manufactureYear;
private static int maxPassengersCount = 300;
public Boeing737(int manufactureYear) {
this.manufactureYear = manufactureYear;
}
public int getManufactureYear() {
return manufactureYear;
}
public static class Drawing {
public static int getMaxPassengersCount() {
return maxPassengersCount;
}
}
}

Boeing737
המחלקה החיצונית, המייצגת מטוס מסוג זה. יש לו קונסטרוקטור עם פרמטר אחד: שנת ייצור ( int manufactureYear
). יש גם משתנה סטטי אחד: המספר המרבי של נוסעים ( int maxPassengersCount
). יהיה לזה אותו ערך עבור כל המטוסים מאותו דגם, אז אנחנו צריכים רק מופע אחד. בנוסף, יש לו מחלקה מקוננת סטטית: Drawing
(המייצגת את השרטוטים ההנדסיים של המטוס). אנו משתמשים במחלקה זו כדי לכלול את כל המידע הרשמי על המטוס. בדוגמה שלנו, לשם הפשטות, הגבלנו את המחלקה הזו לשנת הייצור, אך היא עשויה להכיל מידע רב אחר. 
Drawing
המחלקה הסטטית אינו מאחסן הפניה למופע ספציפי של המחלקה החיצונית. זכרו את דוגמה לאופניים מהשיעור האחרון:
public class Bicycle {
private String model;
private int maxWeight;
public Bicycle(String model, int maxWeight) {
this.model = model;
this.maxWeight = maxWeight;
}
public void start() {
System.out.println("Let's go!");
}
public class Handlebar {
public void right() {
System.out.println("Steer right!");
}
public void left() {
System.out.println("Steer left!");
}
}
}
בשיעור ההוא, דיברנו על כך שכל מופע של Handlebar
המעמד הפנימי, באופן בלתי מורגש עבורנו, מעביר התייחסות למופע של Bicycle
המעמד החיצוני. ללא מופע של המעמד החיצוני, אובייקט של המעמד הפנימי פשוט לא יכול להתקיים. עבור מחלקות מקוננות סטטיות, זה לא המקרה. אובייקט של מחלקה מקוננת סטטית מסוגל לחלוטין להתקיים בעצמו. בהקשר זה, מחלקות סטטיות הן "בלתי תלויות" יותר מאשר לא סטטיות. הדבר היחיד שאתה צריך לדעת הוא שכאשר יוצרים אובייקט כזה, עליך לציין את שם המחלקה החיצונית:
public class Main {
public static void main(String[] args) {
Boeing737.Drawing drawing1 = new Boeing737.Drawing();
Boeing737.Drawing drawing2 = new Boeing737.Drawing();
}
}
מדוע הפכנו את Drawing
הכיתה לסטטית כאשר בשיעור האחרון הפכנו את Seat
הכיתה (המייצגת את מושב האופניים) ללא סטטי? כמו בפעם הקודמת, בואו נוסיף קצת "פילוסופיה" על מנת להבין את הדוגמה :) בניגוד למושב אופניים, המושג של שרטוט הנדסי אינו קשור בצורה נוקשה למושג מטוס. ללא אופניים, חפץ מושב נפרד לאופניים יהיה לרוב חסר משמעות (אם כי לא תמיד, דיברנו על כך בשיעור האחרון). הרעיון של שרטוט הנדסי הגיוני בפני עצמו. לדוגמה, זה יכול להיות שימושי למהנדסים שמתכננים תחזוקת מטוסים. המטוס אינו נחוץ לביצוע התוכנית והוא יכול להיות ממוקם בכל מקום. יש צורך רק בשרטוט ההנדסי. בנוסף, לכל המטוסים מאותו דגם יהיה אותו שרטוט מהנדס, כך שאין קשר הדוק כמו שיש למושב אופניים. לכן, Drawing
עצם אינו זקוק להתייחסות לאובייקט מסוים במטוס. 2. גישה שונה למשתנים ולשיטות של המחלקה החיצונית. מחלקה מקוננת סטטית יכולה לגשת רק לשדות הסטטיים של מחלקה חיצונית. בדוגמה שלנו, Drawing
למחלקה יש getMaxPassengersCount()
שיטה שמחזירה את הערך של maxPassengersCount
המשתנה הסטטי של המחלקה החיצונית. עם זאת, לא נוכל ליצור getManufactureYear()
שיטה במחלקה Drawing
כדי להחזיר את הערך של manufactureYear
. אחרי הכל, manufactureYear
המשתנה אינו סטטי, מה שאומר שהוא חייב להיות שייך למופע ספציפי של Boeing737
. וכפי שכבר גילינו, במקרה של מחלקות מקוננות סטטיות, האובייקט של המחלקה החיצונית עלול להיעדר בקלות. מכאן, המגבלה :) זה לא משנה לאיזה שינוי גישה יש למשתנה סטטי במחלקה החיצונית. גם אם זה private
, למחלקה מקוננת סטטית עדיין תהיה גישה. כל האמור לעיל חל לא רק על גישה למשתנים סטטיים, אלא גם על שיטות סטטיות. חָשׁוּב! בהכרזה על מחלקה פנימית, static
מילת המפתח לא אומרת שאתה יכול ליצור רק אובייקט אחד. אל תבלבל בין אובייקטים למשתנים. אם אנחנו מדברים על משתנים סטטיים, אז כן, קיים מופע יחיד של משתנה מחלקה סטטי, למשל, maxPassangersCount
. אבל כאשר static
מוחל על מחלקה מקוננת, זה אומר רק שהאובייקטים שלה אינם מכילים הפניות לאובייקטים של המחלקה החיצונית. ואנחנו יכולים ליצור כמה מהאובייקטים עצמם שאנחנו רוצים:
public class Boeing737 {
private int manufactureYear;
private static int maxPassengersCount = 300;
public Boeing737(int manufactureYear) {
this.manufactureYear = manufactureYear;
}
public int getManufactureYear() {
return manufactureYear;
}
public static class Drawing {
private int id;
public Drawing(int id) {
this.id = id;
}
public static int getPassengersCount() {
return maxPassengersCount;
}
@Override
public String toString() {
return "Drawing{" +
"id=" + id +
'}';
}
public static void main(String[] args) {
for (int i = 1; i < 6; i++) {
Boeing737.Drawing drawing = new Boeing737.Drawing(i);
System.out.println(drawing);
}
}
}
}
הכרזנו על main()
השיטה ישירות במחלקה המקוננת (אין סיבה מיוחדת לכך - רק כדי שתדע שזה אפשרי), ויצרנו 5 Drawing
אובייקטים. למרות העובדה שאין לנו אובייקט אחד מהמעמד החיצוני. כפי שאתה יכול לראות, זה לא יצר בעיות :) פלט מסוף:
Drawing{id=1}
Drawing{id=2}
Drawing{id=3}
Drawing{id=4}
Drawing{id=5}
ובזה מסתיים השיעור שלנו! ליתר בטחון, אני אשאיר לך קישור לקטע עליהם בתיעוד של אורקל
. אם משהו עדיין לא ברור, קרא אותו. עכשיו הגיע הזמן שאפתור כמה משימות! :)
GO TO FULL VERSION