[מבוסס על השאלה הזאת מStackOverflow]
משהו שבוודאי שמנו לב אליו בפעמים הקודמות, הוא שבמידה ויש לנו שתי פונקציות עם אותו שם, ואותם פרמטרים, הדבר עשוי להיות בעייתי במספר מצבים.
(אנחנו נתקלנו בבעיה עם Indexerים ספציפית, אבל קל להיתקל בזה גם בהקשרים אחרים)
בC# מה שעשו, זה אפשרו לעשות מימוש של Explicit Implementation לממשקים, המאפשר לנו לציין לאיזה ממשק שייכת המתודה שאנחנו רוצים לממש. (ראו גם טיפ מספר 82)
אולי תתפלאו לשמוע, אבל יש שפות בהן הדבר הזה לא אפשרי, למשל שפת Java.
בJava אי אפשר לתת לשתי מתודות אותו שם ואתם פרמטרים, ולמעשה גם אין שם Explicit Implementation.
אז איך הם מסתדרים שם?
דבר ראשון, לJava יש תמיכה בCovariance במימוש ממשקים, למה הכוונה?
נניח שיש לנו איזשהו טיפוסים שמממש כמה ממשקים:
|
|
עכשיו נניח שיש לנו כמה Providerים:
|
|
עכשיו נניח שאנחנו רוצים לממש את שני הממשקים האלה של הProviderים. בC# אין לנו ברירה, ואנחנו חייבים לממש אותם Explicitly:
|
|
בJava יש אלטרנטיבה! אפשר לממש פונקציה אחת שמחזירה את שני הטיפוסים!
|
|
שימו לב שיש פה Covariance בערך ההחזר, כלומר עצם העובדה שDog מממש את שני הממשקים שלנו, גורם לכך שגםProvider מממש את שני הממשקים.
ראו גם טיפים מספר 36-40 על Covariance וContravariance.
מה עוד?
הרי לא תמיד הסיטואציה כל כך פשוטה, למשל אם ערכי ההחזר הם string וint, אי אפשר לעשות טריק כזה.
במקרה הזה יש את הטריק הבא: שמים במחלקה שלנו פונקציות שמביאות את הממשקים שמעניינים אותנו, למשל:
|
|
ויוצרים מחלקות פנימיות שמממשות אותן:
|
|
מה הטריק? הטריק הוא שהמחלקות הפנימיות יכולות לגשת לכל הMemberים של המחלקה Provider, ולכן לממש את הממשק כאוות נפשן! 😃
(ראו גם טיפ מספר 217)
אמנם בC# אנחנו יכולים לפתור את הבעיות האלה בצורה אחרת בעזרת Explicit implementation, אך אפשר להעתיק את הרעיון למספר למקומות שבהם הוא מתאים.
יום עם פולי קפה טובים טוב