ראינו פעם קודמת כיצד אפשר ליצור אופרטורים משלנו.
יש כמה אופרטורים מיוחדים שלא כל כך טריוואלי שאפשר לעשות להם Operator overload.
באחד מהם נפגשנו בעבר (טיפ מספר 2).
אחד האופרטורים הנוספים הוא אופרטור ששמו implicit. זה נראה כמו משהו חדש, אבל בעצם כולנו כבר מכירים אותו:
נניח שיש לנו את הקוד הבא:
|
|
מה בדיוק קורה כאן? ובכן, אם נזכר בטיפ על ההבדל בין Value types וReference types נשים לב שבValue types כמו int וfloat אין ירושה.
לכן מה שקורה כאן זו לא "סתם" המרה ממחלקת בן למחלקת אב, אלא ממש איזשהי המרה המאפשרת לנו להסב את המשתנה הראשונה לסוג של המשתנה השני באופן לא טבעי.
מאחר והסבה זו אינה מאבדת מידע, היא נעשית באופן "שקוף", כלומר implicitly. אם ההסבה הייתה מאבדת מידע (למשל מfloat לint), אז היא לא הייתה שקופה, והיינו צריכים לבצע אותה באופן מפורש.
זה מתבצע באמצעות קריאה של הקומפיילר לפונקציה מתאימה המבצעת הסבה זו.
אנחנו יכולים לעשות דברים כאלה בעצמנו: נניח שיש לנו מחלקה המייצגת מעלות ומחלקה המייצגת רדיאנים:
|
|
נוכל לכתוב הסבה שהיא implicit ביניהם. נכתוב למשל בתוך המחלקה של הרדיאנים:
|
|
ואז נוכל לבצע המרות באופן שקוף:
|
|
שימו לב שזה גם מסוכן, כיוון שאנחנו יכולים לכתוב קוד שלא התכוונו לכתוב ומתקמפל, למשל להחזיר בטעות מפונקציה שאמורה להחזיר מעלות, רדיאנים.
למשל נניח שיש לנו פונקציה שאמורה להחזיר את סכום הזוויות במשולש. נניח שבטעות רשמנו משהו כזה:
|
|
הדבר מתקמפל, אבל לא זאת הייתה הכוונה שלנו, כיוון שעכשיו יוחזר לנו מהפונקציה 180 רדיאנים במעלות, במקום 180 מעלות.
מתי בכל זאת כדאי להשתמש?
כשאתם רוצים לעשות ששני אובייקטים יהיו "שקולים" בלי לרשת אחד מהשני.
למשל, נניח שיש לכם אובייקט משלכם שמייצג שגיאה שאפשר גם לכתוב לLog ולעשות איתו עוד דברים, אז אפשר לעשות הסבה implicit מException לאובייקט שלכם.
עוד דוגמה היא כזאת – נניח שיש לכם אובייקט שמייצג כתובת ונניח שיש לו ייצוג מחרוזתי לכתובת זו (למשל בעזרת הפונקציה ToString). אפשר ליצור הסבה implicit בין המחרוזת המייצגת את האובייקט לאובייקט שלכם. למשל:
|
|
בכל אופן, חשוב לדאוג שההסבה לא תאבד מידע, מאחר והיא מתבצעת באופן בלתי גלוי לעין.
שימו לב שלא נוכל ליצור הסבות ממחלקת אב או הסבות למחלקות אב – אלו שמורות ע"י הקומפיילר.
המשך יום מוסב לטובה