→ חזרו אחורה

פרק 9 - מבוא למחלקות ועצמים

⏱ 16 דקות קריאה

עד עכשיו למדנו לשמור מידע במשתנים בודדים ובמערכים. אבל מה קורה כשרוצים לתאר משהו עם כמה תכונות ביחד - למשל תלמיד, עם שם וגיל וציון? אפשר להשתמש בשלושה מערכים נפרדים, אבל זה מסורבל ומבלבל. הפתרון האמיתי הוא מחלקה (Class).

1. מחלקה היא תבנית, אובייקט הוא מופע

מחלקה היא בעצם "תבנית" או "שרטוט" שמתאר איזה מידע ואיזו התנהגות יהיו לדבר מסוים - למשל "לכל תלמיד יש שם וגיל". אובייקט (Object) הוא "מופע" קונקרטי שנוצר לפי התבנית הזו - למשל התלמיד הספציפי "דנה, גיל 17".

אנלוגיה: חשבו על מחלקה כמו תבנית עוגה, ועל כל אובייקט כמו עוגה אחת שאפו לפי אותה תבנית. אפשר לאפות הרבה עוגות (אובייקטים) מאותה תבנית (מחלקה), וכל אחת יכולה להיות טעימה קצת אחרת.

2. בניית מחלקה עם שדות

שדות (Fields) הם המשתנים ששייכים למחלקה - הם מתארים את המידע שכל אובייקט מהסוג הזה יחזיק.

⁦C#⁩

class Student
{
    public string Name;
    public int Age;
}
            

זו מחלקה שלמה, שמתארת שכל תלמיד יש לו Name (שם) ו-Age (גיל). היא נכתבת בקובץ נפרד, למשל Student.cs. שימו לב ש-public אומר שאפשר לגשת לשדה גם מקבצים אחרים.

3. בנאי (Constructor)

כדי ליצור אובייקט חדש עם ערכים התחלתיים, נכתוב בנאי - מתודה מיוחדת שנקראת בדיוק כמו המחלקה, ורצה אוטומטית בכל פעם שיוצרים אובייקט חדש.

⁦C#⁩

class Student
{
    public string Name;
    public int Age;

    public Student(string studentName, int studentAge)
    {
        Name = studentName;
        Age = studentAge;
    }
}
            

לבנאי אין סוג החזרה (לא void ולא שום דבר אחר) - הוא תמיד נקרא בדיוק כמו המחלקה.

בתוך הבנאי, אנחנו לוקחים את הפרמטרים שהתקבלו ושומרים אותם בתוך השדות של האובייקט החדש.

הבנאי קובע את ה"מצב" (state) ההתחלתי של האובייקט: כל אובייקט חדש מקבל עותק עצמאי משלו של השדות - קריאה ל-new Student("דנה", 17) ואז ל- new Student("יוסי", 16) יוצרת שני אובייקטים נפרדים לגמרי, שכל אחד "זוכר" רק את הערכים שהועברו לבנאי שלו. שינוי שדה באובייקט אחד לא משפיע בכלל על האובייקט השני.

4. יצירת אובייקט ושימוש בו

כדי ליצור אובייקט חדש מהמחלקה, משתמשים במילה new, וקוראים לבנאי עם הערכים הרצויים. כדי לגשת לשדות של האובייקט, משתמשים בנקודה.

⁦C#⁩

Student s1 = new Student("דנה", 17);
Student s2 = new Student("יוסי", 16);

Console.WriteLine(s1.Name + " בת " + s1.Age);
Console.WriteLine(s2.Name + " בן " + s2.Age);
            

Student - סוג המשתנה: אובייקט מסוג תלמיד.

s1, s2 - שני אובייקטים נפרדים לגמרי, כל אחד עם שם וגיל משלו.

s1.Name - גישה לשדה Name של האובייקט הספציפי s1.

5. הוספת מתודה למחלקה

מחלקה יכולה להכיל גם מתודות (בדיוק כמו שלמדנו בפרק המתודות), שיכולות להשתמש בשדות של האובייקט:

⁦C#⁩

class Student
{
    public string Name;
    public int Age;

    public Student(string studentName, int studentAge)
    {
        Name = studentName;
        Age = studentAge;
    }

    public bool IsAdult()
    {
        return Age >= 18;
    }
}
            

עכשיו אפשר לקרוא למתודה על כל אובייקט בנפרד, בדיוק כמו לשדה:

⁦C#⁩

Student s1 = new Student("דנה", 17);
Console.WriteLine(s1.IsAdult());
            
מבט קדימה: בהמשך הדרך תפגשו גם ירושה (Inheritance) - יכולת ליצור מחלקה חדשה שמבוססת על מחלקה קיימת ומרחיבה אותה. זה נושא מתקדם יותר שבנוי בדיוק על מה שלמדנו כאן.

6. טעויות נפוצות

שכחתם new: אי אפשר ליצור אובייקט בלי המילה new - בלעדיה, המשתנה לא יצביע על אובייקט אמיתי.

סוג החזרה בבנאי: בבנאי אף פעם לא כותבים סוג החזרה, אפילו לא void.

בלבול בין שם השדה לפרמטר: אם שם הפרמטר בבנאי זהה בדיוק לשם השדה, צריך להשתמש במילה this כדי להבדיל ביניהם - נושא שנרחיב עליו בהמשך.

🎓 זווית הבגרות

איך זה מופיע בבגרות: מחלקות ואובייקטים הם ליבת חלק ב' של הבגרות - כל שאלה בחלק הזה מתחילה ממחלקה נתונה (או חלקית) שצריך להשלים.

סוג שאלה טיפוסי: השלמת בנאי ומתודה אחת-שתיים במחלקה נתונה, ולפעמים גם כתיבת מתודה חיצונית סטטית שמקבלת מערך של אובייקטים מהמחלקה ומשתמשת במתודות שלה.

טעות נפוצה: לשכוח שכשפרמטר בבנאי חולק שם עם השדה (רק באות ראשונה קטנה/גדולה) צריך להקפיד להשמיש לשדה הנכון, אחרת השדה לא יתעדכן.

מה לזכור למבחן: מתודה חיצונית שמקבלת מערך אובייקטים חייבת להשתמש במתודות הקיימות של המחלקה (כמו IsAdult()) ולא לשכתב את הלוגיקה שלהן מחדש.

7. תרגול

מה יודפס למסך על ידי הקוד הבא?

⁦C#⁩
Student s1 = new Student("דנה", 17);
Student s2 = new Student("יוסי", 19);
Console.WriteLine(s1.IsAdult() + " " + s2.IsAdult());

מה יודפס למסך על ידי הקוד הבא? (השוואה בין השדות של שני אובייקטים)

⁦C#⁩
Student s1 = new Student("דנה", 17);
Student s2 = new Student("יוסי", 16);
Console.WriteLine(s1.Age > s2.Age);

כתבו שדה ציבורי בשם Grade מסוג int בתוך מחלקה.

כתבו שורת קוד שיוצרת אובייקט חדש מסוג Student בשם s1, עם השם "רון" וגיל 15.

כתבו קוד שמדפיס את השדה Name של האובייקט s1.

פרק 8 - מערך דו-ממדי פרק 10 - רקורסיה