בהמשך לפעם הקודמת, ראינו כיצד יכולנו לממש פונקציות של Instance בשפה, גם אם לא היו לנו פונקציות של Instance.
בסוף הפעם הקודמת זרקתי משהו על זה שאפשר גם לממש פונקציות וירטואליות באיזושהי צורה עם Delegate, והפעם נתעמק בפתרון זה.
ובכן, תזכורת:
אנחנו רוצים שנכתב הקוד הבא (הדוגמאות נמצאות בפעם הקודמות), נקבל את ההתנהגות הבאה:
|
|
ובכן, ראינו שהקוד הזה יתרגם לשורות הבאות:
|
|
ולכן אנחנו בעצם רוצים שהפונקציות הסטטיות יקראו לפונקציה המתאימה. למעשה, היינו רוצים למשל שהשורה
|
|
תקרא במקום לפונקציה
|
|
אז איך נוכל לעשות זאת?
אחד העקרונות של OOP הוא שמחלקות אינם מכירות את היורשות מהן. לכן לבדוק במחלקת הבסיס Shape מהו הטיפוס, זו לא אופציה.
מה כן אפשר לעשות? אפשר להשתמש בDelegateים!
איך נעשה את זה? כל Instance יחזיק את המתודות האלה:
|
|
כעת בקריאה למתודות נקרא למתודות האלה:
|
|
ונדאג בConstructorים לאתחל את הDelegate במתודות הנכונות:
בShape זה קל:
|
|
בSquare זה יותר קשה:
|
|
שימו לקסם: כשיכתבו את השורה הזאת למשל:
|
|
היא תתרגם ל
|
|
שתקרא ל
|
|
שתקרא ל
|
|
שתקרא ל
|
|
הקסם הוא שהמתודה היחידה שיש לנו כאן שהיא באמת "וירטואלית" היא הConstructor. וזה לגיטימי שהיא תהיה וירטואלית, כי הרי אנחנו יוצרים עם Constructorים שונים אובייקטים שונים.
הפתרון הזה נחמד, ואם יצא לכם לתכנת בשפות אחרות, קיימת סבירות גבוהה שכך ממומשות שם פונקציות וירטואליות.
אם נחשוב על זה, כעת כל instance שלנו מתנפח במידה אודות כל הפונקציות הוירטואליות שיש לו. זה בסדר עבור delegate אחד או שניים, אבל ברגע שזה גדל, זה מתחיל לתפוס מקום בזכרון.
בפעם הבאה אנחנו ננסה להקטין את המקום הזה בזכרון ע"י יצירת הDelegateים האלה פעם אחת.
המשך יום וירטואלי טוב!