בהמשך לטיפ על Single Abstract Method הבא אליו בJava 8, הנה עוד Feature שמגיע אלינו מJava 8:
הFeature נקרא Virtual Extension Methods.
על Extension Methods בC# דיברנו כבר לא מעט (טיפים 66-75 וגם אחר כך).
בגדול Extension Methods נותנים לנו שני דברים מגניבים:
- אופציה “להוסיף” מתודות לTypeים שכבר קיימים (טיפ מספר 75 למשל)
- אופציה לקבל בחינם מתודות לממשקים ע”י שימוש בפונקציות שהם חושפים (טיפ מספר 84)
היכולת הראשונה יכולה לאפשר לנו יכולות יפות (כמו הרבה מהדוגמאות שראינו), אבל יכולה גם לזבל לנו את הIntellisense בExtension Methods לא רלוונטיים במידה והוספנו Reference ועשינו using לא נכון.
בנוסף, ייתכן כי נשתמש בExtension Method שאין לו “תמיכה של היצרן”, כלומר הוא בד”כ לא נכתב על ידי מי שכתב את המחלקה המקורית, אלא ע”י מישהו חיצוני.
בJava החליטו שהם מממשים Extension Methods בצורה אחרת, כנראה בגלל הבעיות האלה.
איך זה עובד?
נדגים על הדוגמה של טיפ מספר 75.
נניח שיש לנו את הממשק הזה:
|
|
אנחנו רוצים להציע מימוש דיפולטי לTurnOpposite וTurnRight ע"י TurnLeft.
בJava 8 נוכל לעשות זאת כך:
|
|
מה שקורה כאן זה שכשנממש את הממשק Turnable, נצטרך לממש רק את הפונקציה TurnLeft, ונקבל בחינם מימושים לפונקציות TurnRight וTurnOpposite.
עם זאת, קיימת לנו האופציה לדרוס את TurnRight וTurnOpposite למימושים אחרים משלנו.
אם נרצה למנוע מהמממש של הממשק שלנו את האפשרות של לדרוס את הפונקציות האלה, נוכל להחליף את המילה default בfinal:
|
|
זה מזכיר קצת את הסיפור של מחלקה אבסטרקטית.
הדבר הזה מאפשר להתגבר על החסרונות של Extension Methods:
נוכל להוסיף "Extension Methods" רק לממשקים שאנחנו כתבנו.
מצד אחד זו הגבלה, כיוון שלא נוכל להוסיף Extension Methods יפים לטיפוסים שלא שלנו.
מצד שני, זה מאפשר יותר סדר ושליטה על המתודות שמופיעות בIntellisense, ומאפשר Api נקי יותר.
אישית, הדבר שהכי אהבתי כאן זה העובדה שאפשר לממש Extension Method ולדרוס את המימוש הדיפולטי. זה Feature שחסר בC#, וכנראה בלתי אפשרי לעשות בגלל האופן בו מימשו Extension Methods בשפה.
המשך יום מורחב עם קפה טוב.