תכנות מונחה עצמים (OOP) - הורשה - תחביר הורשה

סגור באמצעות טופס זה תוכלו לספר ולהמליץ לחבריכם..
שם השולח:
כתובת דוא"ל של השולח:
שם המקבל:
שלח לכתובת דוא"ל:
הוסף הערה:
פרק המסביר ומדגים את התחביר (Syntax) של הורשה בשפת #C.
תחביר הורשה
 
מאת: ארז קלר

הורדת דוגמאות קוד

ב- #C מגדירים הורשה באמצעות האופרטור : (נקודתיים)
class Derived:Base
המשמעות של האופרטור היא שהמחלקה Derived יורשת את המחלקה Base.
נתחיל בדוגמת קוד פשוטה (InheritanceSample01):
המחלקה Base
 1  : class Base 
 2  : { 
 3  :     private int baseNum; 
 4  :     public Base() 
 5  :     { 
 6  :         baseNum = 1; 
 7  :     } 
 8  :     public Base(int num) 
 9  :     { 
 10 :         this.baseNum = num; 
 11 :     } 
 12 :     public void PrintBase() 
 13 :     { 
 14 :         Console.WriteLine(baseNum); 
 15 :     } 
 16 :     public int BaseNum 
 17 :     { 
 18 :         get 
 19 :         { 
 20 :             return baseNum; 
 21 :         } 
 22 :         set 
 23 :         { 
 24 :             baseNum = value; 
 25 :         } 
 26 :     } 
 27 : } 
בשורה 1 נגדיר את מחלקת הבסיס, בשורה 3 נגדיר את התכונה של מחלקת הבסיס, התכונה baseNum, כמובן שנקפיד להגדיר אותה כתכונה פרטית (Private).

המחלקה Derived
 1  : class Derived : Base 
 2  : { 
 3  :     private int derivedNum; 
 4  :     public Derived() 
 5  :     { 
 6  :         derivedNum = 1; 
 7  :     } 
 8  :     public Derived(int num1, int num2) 
 9  :     { 
 10 :         BaseNum = num1; 
 11 :         derivedNum = num2; 
 12 :     } 
 13 :     public void PrintDerived() 
 14 :     { 
 15 :         PrintBase(); 
 16 :         Console.WriteLine(derivedNum); 
 17 :     } 
 18 :     public int DerivedNum 
 19 :     { 
 20 :         get 
 21 :         { 
 22 :             return derivedNum; 
 23 :         } 
 24 :         set 
 25 :         { 
 26 :             derivedNum = value; 
 27 :         } 
 28 :     } 
 29 : } 
בשורה 1: המחלקה Derived יורשת את המחלקה Base (האופרטור : ), המחלקה Derived יורשת את כל מה שיש במחלקה Base כולל התכונות, המתודות והמאפיינים (ההורשה היא גורפת) ועליהן היא מוסיפה תכונה חדשה (derivedNum) בשורה 3 ומספר מתודות.
מכיוון שכך, במחלקה Derived קיימות שתי תכונות:  baseNum שמתקבלת ממחלקת הבסיס,

ו- derivedNum שמוגדרת במחלקה הנגזרת.
בהקצאת אובייקט מהמחלקה הנגזרת נשלחים לבנאי שני פרמטרים (שורה 8):
האחד עבור התכונה הקיימת במחלקת הבסיס, והשנייה עבור התכונה המוגדרת המחלקה הנגזרת.
שורה 10 היא שורה מעניינת, שימו לב שאין אנו ניגשים לתכונה הפרטית baseNum אלא למאפיין הציבורי BaseNum.
למרות שהמחלקה Derived יורשת את מחלקת הבסיס Base ואת כל מה שמוגדר בה עדיין ההרשאות גישה נשמרות בקנאות, עדיין רק למחלקת הבסיס Base יש גישה לתכונה הפרטית שלה.

Main
 1  : class Program 
 2  : { 
 3  :     static void Main(string[] args) 
 4  :     { 
 5  :         Derived d = new Derived(11, 22); 
 6  :         d.PrintDerived(); 
 7  :         d.BaseNum = 111; 
 8  :         d.DerivedNum = 222; 
 9  :         d.PrintDerived(); 
 10 :  
 11 :     } 
 12 : } 
הדוגמה InheritanceSample01 מדגימה מספר מהעקרונות הבסיסיים של ההורשה,
האובייקט d מהמחלקה Derived  יכול לגשת למתודות והמאפיינים הציבוריים של מחלקת הבסיס (כמו בשורה 7 למשל) משום שהחלקים הציבוריים של מחלקת הבסיס נגישים.
האובייקט אינו יכול לגשת לחלקים הפרטיים של מחלקת הבסיס, העקרונות של הסתרת מידע מתקיימים גם בהורשה.

פלט:
פלט תוכנית הדוגמה InheritanceSample01

מחלקה נגזרת יכולה בתורה לשמש כמחלקת בסיס למחלקה אחרת אשר תיגזר ממנה, לדוגמה :
המחלקה Derived1 יורשת את המחלקה Base , אולם היא גם משמשת כמחלקת הבסיס של המחלקה Derived2 .
Derived2 בתורה יכולה לשמש כמחלקת בסיס למחלקה חדשה אשר תירש אותה ...

 
הורשה - מחלקה בתורה יכולה לשמש כמחלקת בסיס למחלקה חדשה אשר תירש אותה

גישה למרכיבי מחלקת הבסיס

מחלקה יורשת יכולה לגשת לכל הרכיבים הציבוריים של מחלקת הבסיס שלה, כמו כל מחלקה אחרת.
החלקים הפרטיים של מחלקת הבסיס חסומים גם בפני המחלקה הנגזרת, כמו בפני כל מחלקה אחרת.
בדוגמה הקודמת המחלקה Derived יכולה הייתה לגשת ולהשתמש במתודות PrintBase ובמאפיין BaseNum הציבוריים אולם היא מנועה מלגשת לתכונה m_BaseNum של מחלקת הבסיס בגלל היותה מוגדרת כפרטית.
כאשר מדובר על הרשאות גישה למתודות ותכונות אין למחלקה הנגזרת אין שום פריבילגיה על מחלקות אחרות.
המחלקה הנגזרת יכולה לגשת למחלקת הבסיס שלה בצורה ישירה או באמצעות השימוש במילה השמורה base .
את המחלקה הנגזרת בדוגמה הקודמת (InheritanceSample01) ניתן היה לכתוב כך:
 1  : class Derived : Base 
 2  : { 
 3  :     private int derivedNum; 
 4  :     public Derived() 
 5  :     { 
 6  :         derivedNum = 1; 
 7  :     } 
 8  :     public Derived(int num1, int num2) 
 9  :     { 
 10 :         base.BaseNum = num1; 
 11 :         derivedNum = num2; 
 12 :     } 
 13 :     public void PrintDerived() 
 14 :     { 
 15 :         base.PrintBase(); 
 16 :         Console.WriteLine(derivedNum); 
 17 :     } 
 18 : } 
בשורה 10 ובשורה 15 מודגם השימוש במילה השמורה base.

ניתן לומר שממשק המחלקה הנגזרת (רכיבי המחלקה הציבוריים הנגישים מחוץ למחלקה) כוללים את כל החלקים הציבוריים של מחלקת הבסיס בצירוף החלקים הציבוריים של המחלקה הנגזרת.
כלל זה מדגיש עובדה חשובה - המתכנת אשר משתמש במחלקה יכול להתעלם מהעובדה שהיא יורשת מחלקה אחרת (שגם היא, בתורה, יכולה לרשת מחלקה וכו'). המחלקה מהווה מעין "קופסא שחורה" אשר מציעה פעילויות למשתמש בה, מבלי שהוא ייאלץ להתעמק במבנה הפנימי שלה.
 
 
רשימת אתחול
סדר הבנייה של האובייקט הוא מהבסיס לנגזרת, דהיינו, מחלקת הבסיס נוצרת קודם ורק לאחר מכן נוצרת המחלקה הנגזרת. ולכן, כאשר נוצר אובייקט מהמחלקה הנגזרת, מופעל ה- ctor של המחלקה הנגזרת, אשר מפעיל את ה- ctor של המחלקה הבסיסית.
כברירת מחדל הבנאי של המחלקה הנגזרת מפעיל את בנאי ברירת המחדל של מחלקת הבסיס.
ניתן לראות זאת מהפלט של תוכנית הדוגמה הבאה (InheritanceSample02):
 1  : class Base 
 2  : { 
 3  :     public Base() 
 4  :     { 
 5  :         Console.WriteLine("Base Ctor"); 
 6  :     } 
 7  : } 
 8  : class Derived : Base 
 9  : { 
 10 :     public Derived() 
 11 :     { 
 12 :         Console.WriteLine("Derived Ctor"); 
 13 :     } 
 14 : } 
 15 : class Program 
 16 : { 
 17 :     static void Main(string[] args) 
 18 :     { 
 19 :         Derived d = new Derived(); 
 20 :     } 
 21 : } 


פלט:
פלט תוכנית הדוגמה InheritanceSample02

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


 



כל הזכויות שמורות למחבר ©