בדרך לפולימורפיזם - העמסת ועקיפת פונקציות

3
בדרך לפולימורפיזם העמסת ועקיפת פונקציות בעולם התוכן של תכנות מונחה עצמים ושל כתיבת קוד בכלל קיימת שאיפה תמידית לכתוב קוד כמה שיותר פולימורפי ג' נרי כך שנוכל להשתמש ביעילות ובחסכוניות באותן שורות קוד לביצוע פעולות בעלות אופי דומה, על פני שימוש חוזר, שכפול קוד והזזה של נתונים ממקום למקום שלא לצורך. פולימורפיזם, משמעותו, מצב בו קיימות מספר פונקציות שעל אף העובדה שהן חולקות את אותו השם, הן מבצעות פעולות שונות. ראשית, נעסוק בהבדלים בין העמסת פונקציות לעקיפת פונקציות בדרך לכתיבת קוד פולימורפי יותר. הגורם העיקרי המבדיל בין" העמסת" ל" עקיפת" פונקציות הוא מיקומן בהיררכיה המחלקתית. כפי שנהוג לציין בספרות, " העמסת פונקציה" נעשית בצורה אופקית, כלומר הקשר הוא בין פונקציות בעלות אותו שם הנמצאות באותה דרגה של הורשה בהיררכיה המחלקתית, כאשר ההבדל היחיד בינהן הוא מספר ו/ או סוג הפרמטרים שהן מקבלות, בעוד" עקיפת פונקציה" נעשית בצורה אנכית, כלומר הקשר הוא בין פונקציות זהות לחלוטין הנמצאות ברמות שונות בהיררכיה המחלקתית, קרי, פועלות בקשר שבין הbase class לderived class , או אם תרצו, הקשר שבין האבא והבן( או הבת-: ) ) . העמסת פונקציות היתרון הבולט ביותר בהעמסת פונקציות הוא היכולת להשתמש" באותה פונקציה" בדרכים שונות. נראה דוגמה: נניח וקיימת מחלקה בשםRobot ובמחלקה זו העמסנו את הפונקציהSetData באופן כזה שהיא יכולה לקבל פרמטר אחד, שני פרמטרים או לא לקבל פרמטרים בכלל: 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

Upload: -

Post on 29-Jun-2015

1.028 views

Category:

Education


3 download

DESCRIPTION

מאמר שלישי בסדרת מאמרים בנושא תכנות מונחה עצמים, והפעם - העמסת ועקיפת פונקציות

TRANSCRIPT

Page 1: בדרך לפולימורפיזם - העמסת ועקיפת פונקציות

העמסת ועקיפת פונקציות –בדרך לפולימורפיזם

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

נרי כך שנוכל להשתמש ביעילות ובחסכוניות באותן שורות קוד לביצוע פעולות בעלות אופי ' ג–פולימורפי

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

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

. הן מבצעות פעולות שונות

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

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

כלומר הקשר הוא בין פונקציות בעלות , אופקיתנעשית בצורה " העמסת פונקציה", כפי שנהוג לציין בספרות

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

כלומר הקשר הוא בין , אנכיתנעשית בצורה " עקיפת פונקציה"בעוד , או סוג הפרמטרים שהן מקבלות/ו

פועלות בקשר שבין , קרי, פונקציות זהות לחלוטין הנמצאות ברמות שונות בהיררכיה המחלקתית

. ( (:-או הבת )הקשר שבין האבא והבן , או אם תרצו, 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

Page 2: בדרך לפולימורפיזם - העמסת ועקיפת פונקציות

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

אני בכוונה מציין את המרכאות על . שימו לב)" להעמיס" הוא קונסטרקטור אשר ברצוננו SetDataנניח ו

אך בהיעדר הזנת אחד או , פרמטר יחיד או לא יקבל פרמטרים בכלל, פרמטרים2כך שיקבל , (המושג להעמיס

. אנו נשתמש בערכי ברירת מחדל שהוגדרו מראש, יותר מהערכים

: ההצהרה על הקונסטרקטור תיעשה באופן הבא

void SetData ( int=0, int=0, int=0 );

: ומימוש שלו ייראה כך

void SetData ( int x, int y, int z ) { ... };

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

פעמים עם זהות בשם ' אנו נממש את הפונקציה מס, שבהעמסה, הקונסטרקטור שבדוגמה ואמרנו קודם

. הפונקציה ושוני במספר הפרמטרים או סוגם

. צד המשתמשהיא , הסיבה שבגינה ציינתי דוגמה זו

פרמטר , שהרי הוא יכול לקרוא לה עם שני פרמטרים, מדובר לכאורה בפונקציה שהועמסה, עבור המשתמש

? נכון, מעניין. בודד או ללא פרמטרים כלל

Page 3: בדרך לפולימורפיזם - העמסת ועקיפת פונקציות

עקיפת פונקציות

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

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!