# הכמסה, הפשטה ופולימורפיזם — סיכום העקרונות📖 שיעור

## מה זה?

לאורך היחידה תרגלנו כלים קונקרטיים — Properties, ירושה, `abstract`, Interfaces — בלי לעצור ולתת להם שם משותף. שלושת העקרונות המרכזיים של OOP הם בעצם **שמות** לדברים שכבר עשינו: הכמסה (Encapsulation) זה ה-`private`/Properties מהשיעור השני; הפשטה (Abstraction) זה ה-`abstract class`/Interfaces מהשיעורים הרביעי-חמישי; פולימורפיזם זה ה-`virtual`/`override` על `List<Shape>`. השיעור הזה לא מלמד כלים חדשים — הוא נותן להם שפה משותפת.

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

• Encapsulation (הכמסה) — הסתרת פרטי מימוש פנימיים (שדות `private`), וחשיפת גישה מבוקרת בלבד (Properties, מתודות `public`)

• Abstraction (הפשטה) — הצגת "מה" משהו עושה, בלי לחשוף "איך" — `abstract class`/Interface כ-API בלי פרטי מימוש

• Polymorphism (פולימורפיזם) — אותה קריאה מתנהגת אחרת לפי הטיפוס האמיתי בזמן ריצה

• 3 העקרונות + ירושה — ביחד נקראים לעיתים "עמודי ה-OOP", אך ירושה היא **כלי** ליישום שלהם, לא עיקרון בפני עצמו

```csharp
// Encapsulation — from the lesson on Properties
class BankAccount
{
    private double _balance;                         // hidden
    public double Balance => _balance;                // exposed for reading only
    public void Deposit(double amount) => _balance += amount;   // controlled access only
}
```

```csharp
// Abstraction — from the lesson on abstract/Interfaces
abstract class PaymentMethod
{
    public abstract void Pay(double amount);   // "what" — pay; not "how"
}

class CreditCard : PaymentMethod
{
    public override void Pay(double amount) => Console.WriteLine($"Charging card: {amount}");
}
```

```csharp
// Polymorphism — from the lesson on virtual/override
List<PaymentMethod> methods = new List<PaymentMethod> { new CreditCard() /*, new PayPal() ... */ };
foreach (var method in methods)
{
    method.Pay(100);   // each payment method "knows" how to pay in its own way
}
```

## הסבר עיקרי

Encapsulation הוא לא רק `private` — הוא **גם** חשיפה מכוונת. `BankAccount` לא רק מסתיר את `_balance` — הוא בכוונה חושף `Deposit`/`Balance` כערוצי הגישה היחידים, כדי לשמור על מצב תקין. הרעיון הוא לא "להסתיר הכל", אלא לחשוף בדיוק את מה שהקורא צריך, בצורה מבוקרת.

Abstraction עונה על "מה" ולא "איך" — `abstract class PaymentMethod` עם `Pay(amount)` אומרת "כל אמצעי תשלום יודע לשלם סכום" — בלי לפרט **איך** (חיוב כרטיס? בקשת API? המרת מטבע?). קוד שמשתמש ב-`PaymentMethod` (כמו הלולאה בדוגמה) לא צריך לדעת את הפרטים — זו בדיוק המשמעות של "הפשטה": התעלמות מכוונת מפרטים לא-רלוונטיים לקורא.

איך שלושתם עובדים יחד — Encapsulation שומר על מצב פנימי תקין בכל מחלקה בנפרד; Abstraction מגדירה "חוזה" משותף (`PaymentMethod`) בין כמה מימושים שונים; Polymorphism מאפשר לקוד קורא לטפל בכולם דרך אותו חוזה, בלי לדעת איזה מימוש קונקרטי מסתתר מאחוריו. שלושתם ביחד הם מה שהופך מערכת מונחית-עצמים לגמישה ולניתנת-להרחבה בלי לשבור קוד קיים.

## יתרונות

הכמסה מונעת מצב פנימי לא-תקין ומאפשרת לשנות מימוש פנימי בלי לשבור קוד קורא; הפשטה מפחיתה עומס קוגניטיבי — הקורא מתמודד עם "מה" ולא עם כל "איך" בו-זמנית; פולימורפיזם מאפשר הוספת התנהגות חדשה (טיפוס יורש נוסף) בלי לגעת בקוד הקורא הקיים כלל.

## חסרונות

הפשטה-יתר (יותר מדי שכבות `abstract`/Interface לדברים פשוטים) מוסיפה עקיפין מיותרים; שילוב לא זהיר של שלושת העקרונות יחד עלול ליצור היררכיות מסובכות מדי לתחזוקה — נושא שיטופל ביסודיות בשיעורי SOLID הבאים.

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

• Encapsulation = הסתרת מימוש + חשיפה מבוקרת (Properties, `private`)

• Abstraction = "מה" בלי "איך" (`abstract class`/Interface כחוזה)

• Polymorphism = קריאה זהה, התנהגות שונה לפי טיפוס בזמן ריצה

• ירושה היא כלי מימוש לשלושתם, לא עיקרון רביעי עצמאי בפני עצמו

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

• לחשוב ש-Encapsulation = רק "להוסיף `private`" בלי לחשוב על מה כן לחשוף ולמה

• לבלבל בין Abstraction (מה) ל-Encapsulation (הסתרה) — הם קשורים אך לא זהים

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

## סיכום

הכמסה, הפשטה ופולימורפיזם הם שמות לדברים שכבר תרגלנו לאורך היחידה: הכמסה = `private`+Properties ששולטים במצב הפנימי; הפשטה = `abstract class`/Interface שמגדירים "מה" בלי "איך"; פולימורפיזם = `virtual`/`override` שמאפשר לאותה קריאה להתנהג אחרת לפי הטיפוס האמיתי. יחד הם הבסיס שעליו כל שאר הקורס — כולל SOLID ותבניות עיצוב ביחידה הבאה — נבנה.

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

[Microsoft Learn — Object-oriented programming (C#)](https://learn.microsoft.com/dotnet/csharp/fundamentals/object-oriented/)

---

## תרגילים

### תרגיל 1 — זיהוי עקרונות בקוד קיים

**המשימה:** קחו את הקוד של `Shape`/`Circle`/`Rectangle` מהשיעורים הקודמים ביחידה, וסמנו בכתב איפה מופיע כל אחד משלושת העקרונות (הכמסה/הפשטה/פולימורפיזם).

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

### תרגיל 2 — הוספת מימוש פולימורפי

**המשימה:** הוסיפו `class PayPal : PaymentMethod` נוסף לדוגמת `PaymentMethod` מהשיעור, עם `override Pay` משלו, והוסיפו אותו ל-`List<PaymentMethod>` הקיימת.

**בדיקה:** הלולאה הקיימת (בלי שום שינוי בה!) מדפיסה גם את ההתנהגות של `PayPal` החדש כראוי.

---

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

**המשימה:** בנו מערכת "התראות" (Notifications) פשוטה שמדגימה את שלושת העקרונות יחד.

**דרישות:**
1. **הפשטה:** `abstract class Notification` עם `abstract void Send(string message)`
2. **פולימורפיזם:** לפחות שני מימושים — `EmailNotification` ו-`SmsNotification`, כל אחד עם `override Send` משלו, ו-`List<Notification>` שמריצה `Send` על כולם דרך `foreach` אחד
3. **הכמסה:** כל מימוש שומר שדה פרטי (`private`) רלוונטי (למשל כתובת מייל/מספר טלפון), חשוף רק דרך קונסטרוקטור, לא Property פתוח לשינוי חופשי

**בדיקה:** הרצת `Send` על כל הרשימה מדפיסה הודעה מתאימה לכל סוג התראה, דרך אותו `foreach` בדיוק; אין שום גישה ישירה לשדות הפרטיים מחוץ למחלקות.

## מה בפרק הבא

בפרק הבא — **Generics ועקרונות SOLID**: איך כותבים קוד גמיש לכל טיפוס עם `<T>`, וחמשת העקרונות שמנחים תכנון מחלקות ומערכות שקל לתחזק ולהרחיב.
