מדריך C# מונחה עצמים

מדריך C# – תכנות מונחה עצמים: הורשה – Inheritance

‏ • John Bryce

הורשה הינה אחד מהעקרונות החשובים ביותר בתכנות מונחה עצמים (OOP). הורשה מאפשרת לממש את עקרון ה- reuse – שימוש חוזר בקוד ללא צורך לכתוב אותו מספר פעמים.

מימוש הורשה

בכדי לממש הורשה ב C# יש לכתוב במחלקה היורשת את מחלקת הבסיס שלה בצורה הבאה:

  class Base
  {

  }

  class Derived : Base
  {

  }

דגשים חשובים לגבי הורשה:

  • כל מה שיש במחלקה עובר בהורשה כולל: משתנים, properties, פונקציות וכו'. למעט בנאים (c'tors).
  • אלמנטים שמוגדרים כ- private עוברים בהורשה אך לא ניתן לגשת אליהם מהמחלקה היורשת.
  • השימוש במחלקה היורשת הוא כשימוש במחלקה רגילה.
  • במחלקה היורשת חובה להפעיל בנאי כלשהו ממחלקת הבסיס.
  • הבנאי של מחלקת הבסיס יופעל קודם לבנאי של המחלקה היורשת.
  • אם לא נציין במפורש איזה בנאי נרצה להפעיל יופעל אוטומטית הבנאי שאינו מקבל פרמטרים.

הפעלת בנאי ממחלקת הבסיס מתבצעת באמצעות המילה השמורה base ובאותה שיטה בה השתמשנו להפעלת בנאי אחר מאותה מחלקה (באמצעות this):

  class Base
  {
    public Base(int x)
    {
      //...
    }
  }

  class Derived : Base
  {
    public Derived(int x, int y)
      : base(x)
    {
      //...
    }
  }

דריסת פונקציות

לעיתים קיימת פונקציה במחלקת הבסיס אך היא אינה מתאימה בדיוק במימוש שלה למחלקה היורשת. לדוגמא: פונקציה שמדפיסה את כל המאפיינים של המחלקה. לעיתים היא לא מתאימה כלל ולעיתים היא מתאימה חלקית. ב- C# ניתן לדרוס פונקציה שקיבלנו ממחלקת הבסיס ואם נרצה (לא חובה) נוכל להשתמש בתוך המחלקה היורשת גם בפונקציה שקיבלנו ממחלקת הבסיס. השימוש יתבצע באמצעות המילה השמורה base ולאחריה נקודה וקריאה לפונקציה.

לדוגמא:

  class Base
  {
    public void Print()
    {
      //...
    }
  }

  class Derived : Base
  {

    public new void Print()
    {
      //...
      base.Print();
      //...
    }
  }

דוגמא מלאה להורשה:

להלן דוגמא מלאה להורשה הכוללת מחלקת בסיס בשם Person ושתי מחלקות יורשות בשם Employee, Student.

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

תרשים המחלקות:

תרשים המחלקות - הורשה

 

  class Person
 
{
    //Fields:
    string firstName;
    string lastName;

    //Properties:

    public string FirstName
    {
      get { return firstName; }
      set { firstName = value; }
    }

    public string LastName
    {
      get { return lastName; }
      set { lastName = value; }
    }

    //C'tors:

    public Person()
      : this("", "")
    {
    }

    public Person(string firstName, string lastName)
    {
      FirstName = firstName;
      LastName = lastName;
    }

    //Methods:
    public string Print()
    {
      return string.Format("\nName: {0} {1}",
                           FirstName, LastName);
    }
  }
  class Employee : Person
  {
    //Fields:
    private double salary;

    //Properties:
    public double Salary
    {
      get { return salary; }
      set
      {
        if (value < 0)
          throw new Exception("Illegal salary");

        salary = value;
      }
    }

    //C'tors:
    public Employee()
    {
      Salary = 0;
    }

    public Employee(string fName, string lName, double salary)
      : base(fName, lName)
    {
      Salary = salary;
    }

    //Methods:
    public new string Print()
    {
      return base.Print()
             + string.Format("\nSalary: {0}", Salary);
    }
  }

  class Student : Person
  {
    //Fields:
    private int[] grades;

    //Properties:
    public int[] Grades
    {
      get { return grades; }
      set { grades = value; }
    }

    //C'tors:
    public Student()
    {
      Grades = new int[5];
    }

    public Student(string fName, string lName, int[] grades)
      : base(fName, lName)
    {
      Grades = grades;
    }

    //Methods:
    public new string Print()
    {
      string str = base.Print() + "\nGrades:\t";

      foreach (int g in Grades)
        str += g + "\t";

      return str;
    }
  }
 

  class Program
  {
    static void Main(string[] args)
    {
      Employee e1 = new Employee();
      Employee e2 = new Employee("Lior", "Zamir", 25000);

      Console.WriteLine("Employees:");
      Console.WriteLine(e1.Print());
      Console.WriteLine(e2.Print());

      int[] grades = new int[] { 90, 100, 85 };

      Student s1 = new Student();
      Student s2 = new Student("Avi", "Levi", grades);

      Console.WriteLine("\n--------------\n\nStudents:");
      Console.WriteLine(s1.Print());
      Console.WriteLine(s2.Print());

    }
  }

 

פלט התוכנית:

הורשה - פלט

תגיות: , ,

ליאור זמיר

כיום אני ה- Webmaster של תוכנית החדשנות של HPE Software.לפני כן, הייתי מנהל תחום Webmaster ומרצה בכיר בג'ון-ברייס (במשך 9 שנים) בקורסים לפיתוח ותיכנות באמצעות Microsoft .NET, מולטימדיה, בניית אתרי אינטרנט ואינטראנט. פיתוח הדרכה ומתן ייעוץ טכנולוגי.

תגובות בפייסבוק