הורשה היא מנגנון המאפשר לנו להגדיר מחלקה חדשה (יורשת) על בסיס מחלקה קיימת (בסיס). זוהי אבן יסוד בתכנות מונחה עצמים. במחלקה היורשת יהיו באופן אוטומטי כל התכונות והפעולות של מחלקת הבסיס. המחלקה היורשת יכולה להוסיף תכונות ופעולות, ואף להחליף פעולות מסויימות ממחלקת הבסיס. מומלץ לצפות ,תחילה ב- youtube playlist
מטרות הלמידה
מטרות הלמידה
בסיום פרק זה תוכלו:
- להבין את המושג “הורשה” בתכנות מונחה עצמים
- לסרטט היררכיות של הורשה והכלה בין מחלקות
- להבין ולממש את עקרון “הוא סוג של” (IS-A)
- לקרוא, לממש, ולצייר דיאגרמות UML
כתיבה של הורשה ב-C#
public class Animal { }
public class Dog : Animal // Dog inherits Animal
{
}
תרשים UML של שרשרת הורשה
לעיתים נציג מחלקות בתרשים UML. החץ כלפי מעלה - מהיורשת אל מחלקת הבסיס. על צורת הכתיבה של UML יוסבר בהמשך
מימוש בקוד
למימוש פשוט
public class Organism
{
private string name;
private int age;
public Organism(string name, int age)
{
this.name = name;
this.age = age;
}
public override string ToString() => $"{name}, age {age}";
}
public class Mammal : Organism
{
private bool hasFur;
public Mammal(string name, int age, bool hasFur) : base(name, age)
{
this.hasFur = hasFur;
}
public bool GetHasFur() => hasFur;
public void SetHasFur(bool hasFur) => this.hasFur = hasFur;
}
public class Dog : Mammal
{
private string breed;
public Dog(string name, int age, string breed)
: base(name, age, true)
{
this.breed = breed;
}
public string GetBreed() => breed;
public void SetBreed(string breed) => this.breed = breed;
}
סדר פעולות ביצירת עצם ממחלקה יורשת:
- אם לא מצוין
(...)baseבבנאי של מחלקה יורשת, ייקרא אוטומטית בנאי ברירת מחדל של מחלקת הבסיס (אם קיים). - סדר היצירה של אובייקט יורש הוא: קודם בנאי הבסיס, אחריו בנאי המחלקה הנגזרת.
שימוש: הדגמה עם מערך עצמים
Dog[] kennel = new Dog[]
{
new Dog("Rex", 5, "Labrador"),
new Dog("Luna", 2, "Husky"),
new Dog("Milo", 3, "Beagle")
};
for (int i = 0; i < kennel.Length; i++)
{
Console.WriteLine(
$"{i}: {kennel[i]}, breed {kennel[i].GetBreed()}");
}
למימוש מעט יותר משוכלל
בגרסה זו השינויים הבאים:
- שימוש במשתנה סטטי ליצירת מונה של מופעים והקצאת id לכל עצם
- למחלקות השונות הוגדר
()override string ToStringשמחזיר יצוג של העצם - בכל
ToStringנוספה קריאה לאותה הפעולה במחלקת הבסיס. כך שכל מחלקה מטפלת ומוסיפה רק את המידע שלה
public class Organism
{
private static int counter = 0; // counts instances
private readonly int id; // assigned unique id
private string name;
private int age;
public Organism(string name, int age)
{
this.id = counter++;
this.name = name;
this.age = age;
}
public string GetName() { return name; }
public void SetName(string name) { this.name = name; }
public int GetAge() { return age; }
public void SetAge(int age) { this.age = age; }
public int GetId() => id;
public override string ToString() => $"{id}: {name}, age {age}";
}
public class Mammal : Organism
{
private bool hasFur;
public Mammal(string name, int age, bool hasFur) : base(name, age)
{
this.hasFur = hasFur;
}
public bool GetHasFur() => hasFur;
public void SetHasFur(bool hasFur) => this.hasFur = hasFur;
}
public class Dog : Mammal
{
private string breed;
public Dog(string name, int age, string breed)
: base(name, age, true)
{
this.breed = breed;
}
public string GetBreed() => breed;
public void SetBreed(string value) => breed = value;
public override string ToString() =>
base.ToString() + $", breed {breed}";
}
// Example usage
class Program
{
static void Main()
{
Dog[] kennel = new Dog[]
{
new Dog("Rex", 5, "Labrador"),
new Dog("Luna", 2, "Husky"),
new Dog("Milo", 3, "Beagle")
};
foreach (var dog in kennel)
Console.WriteLine(dog);
}
}
פלט
0: Rex, age 5, breed Labrador
1: Luna, age 2, breed Husky
2: Milo, age 3, breed Beagle
רמות גישה (Access Modifiers)
ניתן לקבוע רמות גישה שונות לשדות, תכונות, פעולות ובנאים
טבלה מסכמת:
| נגישות | access modifier |
|---|---|
| נגיש מכל מקום בפרויקט. | public |
| נגיש רק מתוך המחלקה עצמה. | private |
| נגיש מתוך המחלקה עצמה ומתוך מחלקות שיורשות ממנה. | protected |
| נגיש לכל הקבצים באותו Assembly (בבחינת בגרות נרשום public). | internal |
“הוא סוג של” – עקרון ה־IS A
ב-OOP אנו משתמשים בהורשה ליצירת יחס של “הוא סוג של” (IS A).
מחלקת בן יורשת ממחלקת אב ולכן היא סוג של המחלקה שמעליה.
ניתן לבדוק זאת בזמן ריצה בעזרת המילה השמורה is.
דוגמת קוד
public class Animal { }
public class Dog : Animal
{
public void Bark() => Console.WriteLine("Woof!");
}
class Program
{
static void Main()
{
Animal a1 = new Dog();
Animal a2 = new Animal();
if (a1 is Dog d) // pattern matching
d.Bark(); // a1 הוא סוג של Dog → Woof!
if (a2 is Dog)
Console.WriteLine("a2 הוא כלב");
else
Console.WriteLine("a2 אינו כלב");
}
}
סיכום is:
- IS A מייצג הורשה – כלב הוא סוג של בעל־חיים.
isבודק אם אובייקט שייך לטיפוס מסוים.- עם pattern matching (
obj is Dog d) אפשר גם לבצע המרה בטוחה לאותו טיפוס.
סיכום
- הורשה יוצרת יחס “הוא סוג של”.
- סדר בנאים: מהבסיס אל הנגזר.
- שימוש ב-
private,protected,public,internalחשוב כדי לשלוט בגישה. - בבגרות נרשום
publicולאinternal.
תרגיל: הוסיפו מחלקה נוספת WorkingDog עם שדה Task ובנאי מתאים, והדגימו קריאות ל-Getters/Setters.