# מחלקות, שדות וקונסטרוקטורים📖 שיעור

## מה זה?

בשיעורי היסודות ניהלנו תלמיד עם משתנים נפרדים — `studentName`, `studentAge`, `studentGrade` — בלי שום קשר פורמלי ביניהם. אם רוצים 30 תלמידים, צריך 90 משתנים נפרדים (או 3 מערכים מקבילים, שקל לאבד סנכרון ביניהם). מחלקה (`class`) פותרת את זה: מגדירים "תבנית" אחת שמאגדת יחד את כל השדות שקשורים לישות אחת (תלמיד), ואז יוצרים כמה שרוצים **מופעים** (objects) של אותה תבנית.

## מילות מפתח שחשוב לזכור

• Class — תבנית שמגדירה אילו שדות ומתודות שייכים לישות מסוג מסוים

• Object (Instance) — מופע קונקרטי שנוצר מהתבנית, עם ערכים משלו

• Field — משתנה ששייך למחלקה, מחזיק חלק מהמצב (State) של כל מופע

• Constructor — מתודה מיוחדת שרצה **פעם אחת**, בזמן יצירת מופע חדש עם `new`

• `this` — מתייחס למופע הנוכחי עצמו; מבדיל בין שם הפרמטר לשם השדה כשהם זהים

```csharp
class Student
{
    // Fields — the state of each instance
    public string Name;
    public int Age;

    // Constructor — runs once, when a new instance is created
    public Student(string name, int age)
    {
        this.Name = name;   // this.Name = the field; name = the parameter
        this.Age = age;
    }
}

Student student1 = new Student("Dana", 20);
Student student2 = new Student("Avi", 22);

Console.WriteLine(student1.Name);   // Dana
Console.WriteLine(student2.Name);   // Avi — a completely separate instance
```

```mermaid
flowchart RL
    A["class Student<br/>(template)"] -->|"new Student('Dana', 20)"| B["student1<br/>Name=Dana, Age=20"]
    A -->|"new Student('Avi', 22)"| C["student2<br/>Name=Avi, Age=22"]
```

## הסבר עיקרי

Class מול Object — ה-Class הוא ה"תוכנית" (Blueprint) — הוא לא מחזיק ערכים בעצמו, רק מגדיר **אילו** שדות יהיו לכל מופע. ה-Object הוא ה"בית שנבנה לפי התוכנית" — כל `new Student(...)` יוצר מופע עצמאי לגמרי, עם עותק משלו של כל שדה. שינוי ב-`student1.Age` לא משפיע על `student2.Age` — הם שני אובייקטים נפרדים לגמרי בזיכרון, בדיוק כמו ששני `List<T>` שונים לא משתפים איברים.

למה צריך קונסטרוקטור בכלל — בלי קונסטרוקטור, כל מופע חדש היה נוצר עם ערכי ברירת מחדל ריקים (`null`/`0`), ואז היינו צריכים לקבוע כל שדה בנפרד בשורה נפרדת אחרי היצירה — קל לשכוח שדה אחד. קונסטרוקטור מבטיח שכל מופע נוצר עם **כל** הנתונים ההכרחיים מהרגע הראשון.

למה צריך `this` — כשפרמטר הקונסטרוקטור נקרא `name` וגם השדה נקרא `Name` (או אפילו `name` באותיות זהות), C# צריכה דרך להבדיל ביניהם. `this.Name` אומר במפורש "השדה של המופע הנוכחי", לעומת `name` הפרמטר הרגיל.

## יתרונות

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

## חסרונות

שדות ציבוריים (`public`) בלי הגנה מאפשרים לכל קוד חיצוני לשנות אותם ישירות, בלי בקרה — נושא שיטופל בשיעור הבא (Properties ו-Access Modifiers); מחלקות רבות מדי לכל דבר קטן עלולות להוסיף מורכבות מיותרת ליחידות פשוטות.

## נקודות חשובות

• Class = תבנית; Object/Instance = מופע קונקרטי שנוצר ממנה עם `new`

• כל מופע מחזיק עותק עצמאי משלו של כל השדות — שינוי במופע אחד לא משפיע על אחר

• קונסטרוקטור רץ פעם אחת, ביצירת המופע, ומבטיח אתחול נכון

• `this` מתייחס למופע הנוכחי; נחוץ במיוחד כשפרמטר ושדה חולקים שם

## טעויות נפוצות

• לבלבל בין ה-Class (התבנית) לבין Object ספציפי (המופע) — "שיניתי את Student" זה עמום, "שיניתי את student1" ברור

• לשכוח `this.` כשפרמטר ושדה נקראים אותו דבר, ולגרום לשדה להישאר לא מאותחל

• לצפות ששינוי בשדה של מופע אחד ישפיע על מופע אחר — הם עצמאיים לחלוטין

## סיכום

מחלקה (`class`) מגדירה תבנית עם שדות ומתודות משותפים לישות מסוימת; כל קריאה ל-`new` יוצרת מופע (Object) עצמאי עם עותק משלו של כל השדות. קונסטרוקטור רץ פעם אחת ביצירת המופע ומבטיח אתחול תקין, ו-`this` מתייחס למפורש למופע הנוכחי כשצריך להבדיל בינו לבין פרמטר בעל שם זהה.

## דוקומנטציה רשמית

[Microsoft Learn — Classes](https://learn.microsoft.com/dotnet/csharp/fundamentals/types/classes)

[Microsoft Learn — Constructors](https://learn.microsoft.com/dotnet/csharp/programming-guide/classes-and-structs/constructors)

---

## תרגילים

### תרגיל 1 — מחלקה ראשונה

**המשימה:** הגדירו מחלקה `Book` עם שדות `Title` ו-`Author`, וקונסטרוקטור שמקבל את שניהם. צרו שני מופעים שונים והדפיסו את פרטיהם.

**בדיקה:** שני הספרים מודפסים עם פרטים נכונים ונפרדים, בלי שהם "מתערבבים" זה בזה.

### תרגיל 2 — עצמאות בין מופעים

**המשימה:** צרו שני מופעי `Book` עם אותו `Title` בהתחלה. שנו את ה-`Title` של המופע הראשון בלבד, והדפיסו את שניהם.

**בדיקה:** רק המופע הראשון השתנה; השני נשאר עם הערך המקורי — הוכחה שהם עצמאיים.

---

## פרויקט מסכם

**המשימה:** הגדירו מחלקה `BankAccount` עם שדות `Owner` (string) ו-`Balance` (double), וקונסטרוקטור שמקבל שם בעלים ויתרת פתיחה.

**דרישות:**
1. קונסטרוקטור שמקבל `owner` ו-`initialBalance`, ומאתחל את השדות עם `this`
2. יצירת שני מופעי `BankAccount` שונים עם נתונים שונים
3. הדפסת פרטי שני החשבונות בפורמט קריא ("בעלים: X, יתרה: Y")

**בדיקה:** שני החשבונות מודפסים עם נתונים נכונים ונפרדים לגמרי.

## מה בפרק הבא

בפרק הבא — **Properties ו-Access Modifiers**: איך מגנים על שדות מפני שינוי לא מבוקר מבחוץ, בלי לוותר על הנוחות של גישה ישירה.
