פרק 9 - מבוא למחלקות ועצמים
עד עכשיו למדנו לשמור מידע במשתנים בודדים ובמערכים. אבל מה קורה כשרוצים לתאר משהו עם כמה תכונות ביחד - למשל תלמיד, עם שם וגיל וציון? אפשר להשתמש בשלושה מערכים נפרדים, אבל זה מסורבל ומבלבל. הפתרון האמיתי הוא מחלקה (Class).
1. מחלקה היא תבנית, אובייקט הוא מופע
מחלקה היא בעצם "תבנית" או "שרטוט" שמתאר איזה מידע ואיזו התנהגות יהיו לדבר מסוים - למשל "לכל תלמיד יש שם וגיל". אובייקט (Object) הוא "מופע" קונקרטי שנוצר לפי התבנית הזו - למשל התלמיד הספציפי "דנה, גיל 17".
2. בניית מחלקה עם שדות
שדות (Fields) הם המשתנים ששייכים למחלקה - הם מתארים את המידע שכל אובייקט מהסוג הזה יחזיק.
public class Student {
String name;
int age;
}
זו מחלקה שלמה, שמתארת שכל תלמיד יש לו name (שם) ו-age (גיל). היא נכתבת
בקובץ נפרד, למשל Student.java.
3. בנאי (Constructor)
כדי ליצור אובייקט חדש עם ערכים התחלתיים, נכתוב בנאי - מתודה מיוחדת שנקראת בדיוק כמו המחלקה, ורצה אוטומטית בכל פעם שיוצרים אובייקט חדש.
public class Student {
String name;
int age;
public Student(String studentName, int studentAge) {
name = studentName;
age = studentAge;
}
}
לבנאי אין סוג החזרה (לא void ולא שום דבר אחר) - הוא תמיד נקרא בדיוק כמו המחלקה.
בתוך הבנאי, אנחנו לוקחים את הפרמטרים שהתקבלו ושומרים אותם בתוך השדות של האובייקט החדש.
new Student("דנה", 17) ואז ל-
new Student("יוסי", 16) יוצרת שני אובייקטים נפרדים לגמרי, שכל אחד "זוכר" רק את הערכים
שהועברו לבנאי שלו. שינוי שדה באובייקט אחד לא משפיע בכלל על האובייקט השני.
4. יצירת אובייקט ושימוש בו
כדי ליצור אובייקט חדש מהמחלקה, משתמשים במילה new, וקוראים לבנאי עם הערכים הרצויים.
כדי לגשת לשדות של האובייקט, משתמשים בנקודה.
Student s1 = new Student("דנה", 17);
Student s2 = new Student("יוסי", 16);
System.out.println(s1.name + " בת " + s1.age);
System.out.println(s2.name + " בן " + s2.age);
Student - סוג המשתנה: אובייקט מסוג תלמיד.
s1, s2 - שני אובייקטים נפרדים לגמרי, כל אחד עם שם וגיל משלו.
s1.name - גישה לשדה name של האובייקט הספציפי s1.
5. הוספת מתודה למחלקה
מחלקה יכולה להכיל גם מתודות (בדיוק כמו שלמדנו בפרק המתודות), שיכולות להשתמש בשדות של האובייקט:
public class Student {
String name;
int age;
public Student(String studentName, int studentAge) {
name = studentName;
age = studentAge;
}
boolean isAdult() {
return age >= 18;
}
}
עכשיו אפשר לקרוא למתודה על כל אובייקט בנפרד, בדיוק כמו לשדה:
Student s1 = new Student("דנה", 17);
System.out.println(s1.isAdult());
6. טעויות נפוצות
שכחתם new: אי אפשר ליצור אובייקט בלי המילה new - בלעדיה, המשתנה לא יצביע על אובייקט אמיתי.
סוג החזרה בבנאי: בנאי אף פעם לא כותבים לו סוג החזרה, אפילו לא void.
בלבול בין שם השדה לפרמטר: אם שם הפרמטר בבנאי זהה בדיוק לשם השדה, צריך להשתמש במילה this כדי להבדיל ביניהם - נושא שנרחיב עליו בהמשך.
🎓 זווית הבגרות
איך זה מופיע בבגרות: מחלקות ואובייקטים הם ליבת חלק ב' של הבגרות - כל שאלה בחלק הזה מתחילה ממחלקה נתונה (או חלקית) שצריך להשלים.
סוג שאלה טיפוסי: השלמת בנאי ומתודה אחת-שתיים במחלקה נתונה, ולפעמים גם כתיבת מתודה חיצונית סטטית שמקבלת מערך של אובייקטים מהמחלקה ומשתמשת במתודות שלה.
טעות נפוצה: לשכוח את this כשפרמטר בבנאי חולק שם
עם השדה - מה שגורם לשדה לא להתעדכן בפועל (הוא "משבש" את עצמו).
מה לזכור למבחן: מתודה חיצונית שמקבלת מערך אובייקטים חייבת
להשתמש במתודות הקיימות של המחלקה (כמו isAdult()) ולא לשכתב את הלוגיקה שלהן מחדש.
7. תרגול
מה יודפס למסך על ידי הקוד הבא?
Student s1 = new Student("דנה", 17);
Student s2 = new Student("יוסי", 19);
System.out.println(s1.isAdult() + " " + s2.isAdult());
מה יודפס למסך על ידי הקוד הבא? (השוואה בין השדות של שני אובייקטים)
Student s1 = new Student("דנה", 17);
Student s2 = new Student("יוסי", 16);
System.out.println(s1.age > s2.age);
כתבו שדה בשם grade מסוג int בתוך מחלקה, בלי לציין מגדיר גישה (כמו בדוגמאות שראינו).
כתבו שורת קוד שיוצרת אובייקט חדש מסוג Student בשם s1, עם השם "רון" וגיל 15.
כתבו קוד שמדפיס את השדה name של האובייקט s1.