5.1.4. סוגי Overriding

  • החלפה (Replacement) – המימוש החדש של הפונקציה מחליף את המימוש שהיה קיים במחלקת הבסיס – לבן יש מימוש חדש של הפונקציה והוא מפסיק להכיר את הפונקציה שהייתה קיימת במחלקת האב. בשפת Eiffel, למשל, קיים סוג Override זה.
  • עידון (Refinement) – הפונקציה החדשה "מעדנת" את הקוד של הפונקציה הראשונה – היא מסוגלת להשתמש בפונקציה המקורית המוחלפת. במקרים רבים הפונקציה הנורשת קוראת למתודה המקורית לביצוע הפעולה (שימוש למשל ב-super בשפת Little Smalltalk).

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

השאלה שנשאל היא על מי מוטלת האחריות ליצור ולהשתמש בקשר.



הגישה המקובלת – Alpha Refinement – המחלקה החדשה אחראית על הקשר עם הגרסא הישנה.

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

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

שימוש ב-Beta Refinement מאפשר לנו לשלוט על התאימות בצורה טובה יותר. מחלקת האב יכולה להגדיר מה בדיוק יהיה מותר למחלקות הנגזרות לשנות ומה לא.

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

מאת: ניצן

Borland style vptr

לפי מה שאני מכיר:
"חסרון בגישה זו: גם כאשר איננו משתמשים ב-dynamic binding – אנחנו משלמים במקום"
לא נכון , עבור מחלקה A שאין לה מתודות דינמיות לא יווצר כלל המצביע, ולמשל עבור מחלקה B שיורשת מA פשוט נוסיף בהתחלה את המצביע, ואחרי הבלוק של A את שאר האינפורמציה של B . וככה לא משלמים על מה שלא משתמשים ועקרונות C++ נשמרים.
מה שכן באמת הcasting קצת יותר מסובך....
שיתוף:
| עוד