בדרך לפולימורפיזם - העמסת ועקיפת פונקציות
DESCRIPTION
מאמר שלישי בסדרת מאמרים בנושא תכנות מונחה עצמים, והפעם - העמסת ועקיפת פונקציותTRANSCRIPT
העמסת ועקיפת פונקציות –בדרך לפולימורפיזם
בעולם התוכן של תכנות מונחה עצמים ושל כתיבת קוד בכלל קיימת שאיפה תמידית לכתוב קוד כמה שיותר
נרי כך שנוכל להשתמש ביעילות ובחסכוניות באותן שורות קוד לביצוע פעולות בעלות אופי ' ג–פולימורפי
. שכפול קוד והזזה של נתונים ממקום למקום שלא לצורך, על פני שימוש חוזר, דומה
, מצב בו קיימות מספר פונקציות שעל אף העובדה שהן חולקות את אותו השם, משמעותו, פולימורפיזם
. הן מבצעות פעולות שונות
. נעסוק בהבדלים בין העמסת פונקציות לעקיפת פונקציות בדרך לכתיבת קוד פולימורפי יותר, ראשית
. פונקציות הוא מיקומן בהיררכיה המחלקתית" עקיפת"ל" העמסת"הגורם העיקרי המבדיל בין
כלומר הקשר הוא בין פונקציות בעלות , אופקיתנעשית בצורה " העמסת פונקציה", כפי שנהוג לציין בספרות
כאשר ההבדל היחיד בינהן הוא מספר , אותו שם הנמצאות באותה דרגה של הורשה בהיררכיה המחלקתית
כלומר הקשר הוא בין , אנכיתנעשית בצורה " עקיפת פונקציה"בעוד , או סוג הפרמטרים שהן מקבלות/ו
פועלות בקשר שבין , קרי, פונקציות זהות לחלוטין הנמצאות ברמות שונות בהיררכיה המחלקתית
. ( (:-או הבת )הקשר שבין האבא והבן , או אם תרצו, derived class – ל base class –ה
העמסת פונקציות
. בדרכים שונות" באותה פונקציה"היתרון הבולט ביותר בהעמסת פונקציות הוא היכולת להשתמש
: נראה דוגמה
באופן כזה שהיא יכולה לקבל SetData ובמחלקה זו העמסנו את הפונקציה Robotנניח וקיימת מחלקה בשם
: שני פרמטרים או לא לקבל פרמטרים בכלל, פרמטר אחד
void SetData( ) { cout << "You have not set any data..." << endl; }
void SetData ( int x ) { cout << "Data Recorded: " << x << endl; }
void SetData ( int x, int y ) { cout << "Data Recorded: " << x << " " << y << endl; }
: אז נוכל לבצע הקריאות, R2D2ונניח וקיים הרובוט
R2D2.SetData( );
R2D2.SetData(5);
R2D2.SetData(7,9);
: ולצפות לפלט הבא
You have not set any data...
Data Recorded: 5
Data Recorded: 7 9
. שאני מרגיש שיש צורך לעמוד על קיומה, סוג של אנקדוטה קטנה. לעניין זהדוגמה עקיפהברצוני להציג
אני בכוונה מציין את המרכאות על . שימו לב)" להעמיס" הוא קונסטרקטור אשר ברצוננו SetDataנניח ו
אך בהיעדר הזנת אחד או , פרמטר יחיד או לא יקבל פרמטרים בכלל, פרמטרים2כך שיקבל , (המושג להעמיס
. אנו נשתמש בערכי ברירת מחדל שהוגדרו מראש, יותר מהערכים
: ההצהרה על הקונסטרקטור תיעשה באופן הבא
void SetData ( int=0, int=0, int=0 );
: ומימוש שלו ייראה כך
void SetData ( int x, int y, int z ) { ... };
ומימוש אחד עבור , הרי שיש לנו הצהרה אחת, לא באמת ביצענו העמסת פונקציה במקרה זה, אם כן
פעמים עם זהות בשם ' אנו נממש את הפונקציה מס, שבהעמסה, הקונסטרקטור שבדוגמה ואמרנו קודם
. הפונקציה ושוני במספר הפרמטרים או סוגם
. צד המשתמשהיא , הסיבה שבגינה ציינתי דוגמה זו
פרמטר , שהרי הוא יכול לקרוא לה עם שני פרמטרים, מדובר לכאורה בפונקציה שהועמסה, עבור המשתמש
? נכון, מעניין. בודד או ללא פרמטרים כלל
עקיפת פונקציות
. נעסוק בהמשך, ובמימושים מתקדמים יותר, נציין את הגישה הישירה לביצוע העקיפה, עבור עקיפת פונקציות
Base Class –פונקציה שעברה בירושה מה " להגדיר מחדש"היתרון העיקרי בעקיפת פונקציות הוא היכולת
. אך תבצע פעולה מותאמת אישית עבור היורש, כך שתישאר בעלת אותו השם ואותן התכונות
: נוכל לראות זאת בדוגמה הבאה
. Optimus וR2D2 ולה תתי מחלקות בשמות Robotנניח וקיימת מחלקה בשם
ומכאן שגם , "אני רובוט אב" הוא עונה Base Class- על הרובוט ב;( )WhatAreYouכשמריצים את הפונקציה
. היא הנכונה עבורו" אני רובוט בן"אך ברור לכל שהתשובה , הבנים שלו ירשו את היכולת לענות תשובה זו
אך , בה יוכל הבן לומר מי הוא באמת, למשל;( )WhatAreYou2כמובן שיכולנו ליצור פונקציה נוספת בשם
ברצוננו לשמור על המבנה הנוכחי מבלי להוסיף פונקציות מיותרות שרק יעמיסו על הקוד ועלולות לגרום
... ולומר שהוא אב" לשקר"לבלבול עקב האפשרות של הבן
אנו נבצע זאת על ידי שימוש בהגדרת . על מנת להתאים אותה לצרכי הבן" עקיפת פונקציה"עלינו לבצע , על כן
ובכך , (הדבר אפשרי היות והפונקציות נמצאות ברמות היררכיה שונות)פונקציה הזהה לחלוטין לזו של האב
: את פונקצית האב באופן הבא" לדרוס"
class Robot {
void WhatAreYou( ) { cout << "I'm Robot, The father of all robots" << endl; }}
class R2D2: public Robot {
void WhatAreYou( ) { cout << "I'm R2D2, The child of class Robot!" << endl; }}
class Optimus: public Robot {
void WhatAreYou( ) { cout << "I'm Optimus, The child of class Robot!" << endl; }}
נוכל לבצע את הקריאות , ;Optimus robot3;, R2D2 robot2;, Robot robot1ובהנחה וקיימים הרובוטים
: הבאות
robot1.WhatAreYou( );
robot2.WhatAreYou( );
robot3.WhatAreYou( );
: ולצפות לפלט הבא
I'm Robot, The father of all robots!
I'm R2D2, The child of class Robot!
I'm Optimus, The child of class Robot!