
delegate): טיפוס שמחזיק מצביע לפונקציה, ומאפשר להעביר פונקציה כפרמטר ולקרוא לה דרך משתנה.delegate. לדוגמה, delegate double MathOperator(double a, double b); מתאר כל פונקציה שמקבלת שני דאבלים ומחזירה דאבל.MathOperator op = add;.add ואחר כך ל-sub, והקריאה תפעיל את מה שהוא מצביע עליו באותו רגע.Stock צריכה לדעת את המגמה של המניה, אבל לא אמורה להכיר את StockMarketTrends.first מחזירה את הפריט הראשון, או את הראשון שעונה לתנאי שמועבר בדלגייט.any בודק אם פריט כלשהו עונה לתנאי, ו-all בודק אם כל הפריטים עונים לו.null במקום לקרוס כשאין פריט מתאים.p => p.x == p.y.הטקסט המלא של הדקות הראשונות בהרצאה «מצביע לפונקציה - Delegate» בקורס הווידאו של PracticU – כתוביות בעברית עם זמן התחלה לכל פסקה. כך תוכלו לקרוא ולחפש את הנושאים לפני שמתחילים ללמוד.
אנחנו מגיעים לנושא שנקרא delegates זה נושא מאוד מאוד חשוב בעולם פיתוח התוכנה וobject oriented ומאיזושהי סיבה הוא גורם לבלבול לא קטן אצל מתכנתים מתחילים בעולם הobject oriented.
delegate זה סך הכל מצביע לפונקציה זאת תהיה ההגדרה הפשוטה ביותר עבור delegate אם יש לנו פונקציה פונקציה יושבת איפשהו בזיכרון של התוכנית שלנו לפונקציה יש כתובת ואם יש לנו פונקציה ואנחנו יכולים לקרוא לה לפי השם שלה או אנחנו יכולים לקרוא לה אם יש לנו את הכתובת שלה.
אם אנחנו מכירים אותה ויש לנו את השם שלה אז כמובן אנחנו נקרא לה עם השם כמו שעשינו עד היום. אבל אם אין לנו את השם שלה ואנחנו עדיין רוצים לקרוא לה מישהו יכול לתת לנו את הכתובת שלה מי שמכיר אותה ולא יש את השם שלה וכך אנחנו יכולים להחזיק את הכתובת שלה ולפי הכתובת לקרוא לה.
האובייקט שמחזיק את הכתובת של הפונקציה זה הדלגנט. בואו נראה כמה דוגמאות. קודם כל נניח שיש לנו פה איזושהי פונקציה, זה לא משנה אם היא סטטית או לא, שמחזירה לנו את דאבל והיא נקראת add והיא מקבלת a וb ומה שהיא עושה היא מחזירה את a ועוד b. בואו נגיד שיש לנו פה עוד פונקציה שנקראת sub שמחזירה לנו את a מינוס b.
כעת אנחנו רוצים בתוכנית לקרוא לשתי הפונקציות האלה. בואו ניקח איזשהו double sum שווה add ולהציג את sum.
כמובן שאנחנו הולכים לראות שהכל בסדר ומוצג אבל אנחנו יכולים להציב מצביע על הפונקציה הזאת כלומר לשמור את הכתובת שלה במשתנה שהוא מצביע עליה ולקרוא לה פונקציה דרך המצביע הערה אם יש לנו גישה לפונקציה ויש לנו את השם שלה והכל בסדר כמובן שאני לא ארצה לעשות את זה אבל לצורך הדוגמה רק בשביל לראות איך אנחנו יכולים להציב מצביע על פונקציה ולקרוא לה דרך המצביע בואו נעשה את זה אפילו שאנחנו
לא חייבים כרגע מה שאנחנו צריכים לעשות קודם כל ולבנות טיפוס נתונים בעזרת המילה delegate שממנו אנחנו ניצור משתנה והמשתנה יוכל להכיל את הכתובת של הפונקציה.
אז בעצם יש לנו פה את הטיפוס נתונים שאנחנו הולכים לבנות וממנו לאחר מכן נפתח משתנה. זה מתבצע על ידי המילה השמורה delegate. איך אנחנו בונים את טיפוס הנתונים?
טיפוס הנתונים נבנה כך שהוא מתאר את החתימה של הפונקציה שעליה הוא יכול להצביע. אם הפונקציה שלנו מקבלת שני דאבלים ומחזירה דאבל, מן הסתם זה מה שאנחנו רוצים לעשות, דאבל בצורה כזאת.
השם של הפונקציה הולך להיות השם של הטיפוס הנתונים. לדוגמה, אנחנו מדברים על איזשהו מתמטי אופרטור, או נקרא לזה מאף אופרטור.
זה בעצם דלגייט שאומר, אני מסוגל להצביע על כל פונקציה שמקבלת שני דאבלים ומחזירה דאבל אחד, כנראה שאתם רוצים לבצע איזושהי פעילות מתמטית פלוס, מינוס, כפול, חילוק, איזה שבא לכם אז קראתי לדלגייט הזה math operator.
אז השלב הראשון יהיה ליצור את טיפוס הנתונים החדש שנבנה על ידי המילה השמורה דלגייט. שימו לב שטיפוס הנתונים זה המילה הזאת בטורקיז, כל הצבעים של הטורקיז מתארים טיפוסי נתונים.
לאחר מכן אנחנו רוצים בקוד לפתוח אובייקט מהדלגייט. נקרא לו function address, מפני שמה שהוא מחזיק זה את הכתובת של הפונקציה.
אז בואו ניצור אובייקט חדש והקונסטרקטור שלו מקבל כתובת של פונקציה שמקבלת שני דאבלים ומחזירה דאבל. אוקיי, הנה הפונקציית add אבל מה הכתובת שלה?
אז החוק אומר כתובת של פונקציה זה תמיד השם שלה. זאת אומרת אם אני פשוט רושם את השם זה הכתובת. שימו לב שאני לא קורא לה ולכן אני לא פותח סוגריים.
עוד הייתה מחזירה לי דאבל והייתי שולח דאבל ורק השם בלי כלום אז כעת יש לנו את המשתנה או האובייקט funk address שמצביע על הפונקציה add אנחנו עכשיו יכולים לקרוא לפונקציה add על ידי האובייקט function address כאילו שהוא פונקציה רגילה אם אנחנו פותחים סוגריים אנחנו רואים שהוא אומר תביאו לנו ערכים ואני אקרא לפונקציה ואני אחזיר לכם ערך בואו נריץ
נראה שקיבלנו את אותו הדבר, כעת אנחנו יכולים ללכת ולהגיד יש לנו עוד משתנה דאבל סבטראקט והוא שווה לפאנקשן אדרס ואשר לפני זה פאנקשן אדרס הולך לקבל אובייקט חדש שמצביע לפונקציה סאב, זאת אומרת שהחלפנו את ההצבעה שלו, אמרנו לו שעכשיו אתה בעצם מקבל בכלל אובייקט אחר לגמרי שהאובייקט הזה מכיל את הכתובת של סאב וכעת
אנחנו קוראים לו עם סאב. בואו נסתכל, לא הדפסנו את זה, רק שנייה. ויש לנו עכשיו מינוס 11, זאת אומרת, טופ פוינטר הצביע, פעם אחת היה לו אובייקט שמצביע לפונקציה add, ואז קראנו לפונקציה add דרך הפוינטר, ופעם אחת הוא הצביע לפונקציית sub. אוקיי, עכשיו אנחנו בעצם יכולים גם להגיד דבר כזה, במקום לכתוב את כל התחביר של יצירת אובייקט
ולתת לו בקונסטרקטור את הכתובת של הפונקציה, פשוט לכתוב דבר כזה. ברגע שאנחנו כותבים איזשהו Object Delegate שווה לשם של פונקציה, מאחורי הקלעים המערכת יוצרת לנו אובייקט ונותנת לקונסטרקטור שלו את הפונקציה.
אנחנו יכולים לעשות את זה גם כאן. זה לא שאין לנו אובייקט, יש לנו אובייקט, פשוט תחביר יותר מקוצר. בואו נבדוק ונראה שקיבלנו את אותו הדבר.
אז למעשה מה שראינו כאן זה הדגמה הכי פשוטה של מה זה Delegate, וכעת אנחנו הולכים לראות איפה אנחנו יכולים להשתמש עם הדבר הזה באובג'קט אוריינטד ובמחלקות שאנחנו בונים.
אז מהי הדוגמה שאנחנו הולכים לראות? דבר ראשון אנחנו צריכים להבין למה בעצם עלינו להשתמש באובייקט דלגייט. הרי בדוגמה הזאת אנחנו יכלנו לקרוא גם ל-ad בלי להציב עליה איזשהו פוינטר כי אנחנו מכירים את פונקציית ad ולכן אנחנו יכולים לקרוא לה.
במקרה כזה אין לי שום סיבה להשתמש באובייקט דלגייט. מתי אני רוצה להשתמש באובייקט דלגייט? כאשר אני רוצה לקרוא לפונקציה, אבל אני לא מכיר אותה כי היא לא נמצאת במחלקה שלי.
היא נמצאת במחלקה אחרת שאין לי שום גישה אליה ואני לא מכיר אותה. זאת הסיבה שעליי להשתמש באובייקט דליגריט. ובואו ניקח דוגמה כזאת.
נניח שאנחנו מתעסקים באיזושהי תוכנה שעושה כל מיני חישובים על מניות בבורסה. אני שנייה יוריד את כל הקודים הקודמים שכתבתי, אני אשים אותם בהערה בכדי שהם לא יפריעו לנו.
כעת אנחנו הולכים לבנות איזושהי מחלקה שמטפלת בכל מיני דברים שקשורים לבורסת המניות. נתחיל עם מחלקה שהתפקיד שלה זה להחזיר לנו מגמות של מניות בבורסה.
נקרא למחלקה הזאתי Stock Market Trends. יש לנו פה מחלקה שהתפקיד שלה זה להגיד לנו מה המגמה של כל מיני מניות. נותנים למחלקה הזאת איזשהו שם של חברה והיא מחזירה לנו ערך שמציין האם יש לה מגמה של עלייה כרגע או ירידה או בעצם לא עלייה ולא ירידה כלומר אין שום שינוי. לצורך כך בואו נבנה איזשהו אינם שנקרא טרנד והוא מגדיר לנו מגמה שיכולה להיות או לא ידועה נניח
שלחו לנו חברה לא ידועה או מגמת ירידה או אין שום שינוי או עלייה כעת ניגש למחלקה הזאת סטוק מרקט טרנד ונבנה פה פונקציה שמחזירה טרנד נקראת get trend מקבלת איזשהו שם של חברה ובוא נניח מסתכלת כרגע באיזשהו מאגר נתונים לראות ממש ממש עכשיו ברגע שקראו לפונקציה מה המגמה של אותה חברה בבורסה
אנחנו כמובן כרגע נעשה איזושהי הדמיה בוא נגיד סוויץ' ונגדיר כזה דבר אנחנו עושים סוויץ' על הקומפני שקיבלנו במידה ושלחו לי את מיקרוסופט אנחנו מחזירים שהיא בעלייה במידה ושלחו לנו את IBM אנחנו מחזירים שהיא במגמת ירידה במידה ושלחו לנו את אפל אפל כרגע גם כן נמצאת בעלייה כמובן אני סתם לוקח ערכים שרירותיים במידה ושלחו לנו גוגל, נניח שכרגע אין שום
שינוי. גוגל פחות או יותר תמיד בעלייה, אין שום שינוי כרגע. יש לנו פה צורך בנקודותיים ופה נקודותיים.
במידה ושלחו לנו משהו אחר, אנחנו מחזירים unknown. אני לא יודע איזה מגמה, איזה חברה זאת, אבל אני מחזיר unknown. אז כתבנו כרגע איזושהי פונקציה שכמובן עושה הדמיה למצב שבו היא נכנסת לבורסה, נותנת לנו מידע בזמן אמת על מגמות של מניות, כלומר מגמה האם החברה הזאת נמצאת בעלייה מתמדת או בירידה מתמדת או אין שום שינוי, כלומר
לא אם יש לנו פיק קטנצ'יק של עלייה, אלא מה המגמתיות של כמה ימים או כמה שעות, תלוי מה קורה כרגע בבורסה. ובוא נניח שזאת המחלקה שעשינו וזאת הפונקציה get trend והכל בסדר.
כעת אנחנו הולכים לבנות מחלקה נוספת שמתארת לנו מניה בואו נקרא לה סטוק והמחלקה הקטנה הזאת מתארת מניה אחת מה יש לנו במניה יש לנו את החברה של המניה יש לנו קורנט ואליו שכרגע נסחרת בבורסה כמה המניה כרגע בזמן הווה בבורסה ובוא נניח שנכתוב פה את כל הדברים הסטנדרטיים שיש לנו יש לנו סיטור רק יש לנו סיטור שמקבל כל הפרמטרים נכניס בקומפני את הקומפני, קורנט וליו,
יש לנו פה את הפרינט, תפיס את הערכים וכעת אנחנו רוצים שתהיה לנו איזושהי פונקציה שבוא נניח אנחנו רוצים אותה במניה עצמה שמחזירה לנו ערך בוליאני והפונקציה נקראת is good to buy.
האם או לא טוב לקנות כרגע את המניה הזאת? האם כדאי לנו כרגע לקנות את המניה או שלא כדאי לקנות את המניה? ובואו נניח שאנחנו רוצים את הפונקציה הזאת בתוך המחלקה סטוק.
סטוק אומרת האם כדאי לקנות אותי או לא כדאי לקנות אותי. נניח שזה מה שהיינו רוצים בתוכנית. אז לצורך החישוב האם כדאי לקנות או לא כדאי לקנות, אנחנו חייבים לדעת מה המגמה של המניה כרגע בבורסה.
זאת אומרת שאנחנו צריכים את הנתון שמגיע מהמחלקה הזאת, מהסטוק מרקט טרנדס. בוא נניח שאין לנו שום יכולת להגיע לאובייקט מסטוק מרקט טרנד.
אנחנו לא אמורים להכיר בכלל את המחלקה הזאת מתוך סטוק. מנייה מטפלת בעצמה. מנייה לא אמורה להכיר מחלקות אחרות שקשורות למגמות בבורסה או שקשורות לכל הבורסה.
לכן מה שאנחנו יכולים לעשות בשביל לדעת מה המגמה של אותה מנייה זה לומר פה בסוגריים מי שרוצה לקרוא לו פונקציה הזאת ושאנחנו נגיד לו האם כדאי לקנות את אותה המנייה או לא לקנות את אותה המנייה, המנייה הנוכחית כל מה שהוא צריך לעשות זה להביא לנו את הפונקציה
שאומרת לנו מה המגמה של המנייה ואנחנו כבר נעשה חישוב לפי הפונקציה הזאת וניתן לו נתון שאומר לקנות או לא לקנות. איך בדיוק מביאים לי פונקציה? מה שאנחנו צריכים לעשות זה לקבל מצביע לפונקציה דלגייט.
אם אנחנו נקבל כאן דלגייט בסוגריים לפונקציה שזאת בדיוק החתימה שלה והיא מיועדת להגיד לי מה מגמה של מניה אני אוכל להשתמש בה בשביל לקבל החלטה אם לקנות או למכור את המניה או יותר נכון האם בכלל כדאי לקנות אותה.
לכן אנחנו צריכים לבנות פה דלגייט. הדלגייט צריך להיות בנוי בדיוק בחתימה שעליה הוא הולך לקרוא. זה חוק בנוגע לדלגייטס. דלגייט מסוגל לקרוא לפונקציות שנבנו באותה חתימה של הדלגייט.
אוקיי, אז יש לנו פה דאבל דלגייט, נעתיק מפה את החתימה הזאת, נדביק אותה פה, נשים נקודה פסיק ונשנה את השם לאיזשהו דלגייט שמסוגל להגיד לנו האם כדאי לקנות או למכור.
ונקרא לדלגייט הזה טרנד מנאג'ר. ואני מזכיר לכם, זה הערך המוחזר בחתימה, זה הפרמטרים שמתקבלים בחתימה והשם שנמצא כאן בין הערך המוחזר לבין הפרמטרים זה השם של הטיפוס החדש שאנחנו בונים טרנד מנאג'ר כעת אנחנו יכולים לבוא לפה ולקבל לפונקציה אובייקט מטיפוס טרנד מנאג'ר נקרא לו פונקצ'ן אדרס כרגע למרות שבמציאות נותנים לזה שמות יותר
משמעותיים כי כל אובייקט דלגייט זה בעצם כתובת של פונקציה וכעת אנחנו יכולים לבצע איזשהו חישוב אז בואו נפתח אובייקט טרנד נקרא לפונקציה שאנחנו לא מכירים, שימו לב אנחנו בדיוק בתוך המחלקה סטוק, אנחנו לא מכירים את הפונקציה שנקראת גט טרנד.
בזמן שכתבנו את המחלקה הזאת אין לנו מושג מה הפונקציה הזאת גט טרנד ולכן אנחנו פשוט קוראים לה דרך הכתובת שמישהו הביא לנו. שולחים את ה-company וקיבלנו את המגמה של הפונקציה של המניה גט טרנד.
כעת אנחנו יכולים לבצע איזושהי בדיקה או חישוב משלנו. אם המגמה כרגע היא בעלייה וגם בוא נניח דייט טיים נקודה now נקודה day of week תן שווה לטיוזדיי אז עכשיו נחשב תחילת השבוע ורק אם כרגע תחילת השבוע והמגמה בעלייה אנחנו רוצים לקנות את המנייה הזאת או לאשר לקנות אותה אחרת אנחנו לא
רוצים סתם זרקתי פה איזשהו חישוב שבוודאות הוא הזוי לגמרי אבל זה לא הנקודה, הנקודה היא שיש לנו כאן פונקציה שאני לא אמור להכיר במחלקה שלי, אני רק אומר תביאו לי את הפונקציה הזאת על ידי שליחת דליגייט לכתובת שלי, ואני יכול לקרוא לה עכשיו בשביל לדעת מה המגמה של המנייה הזאת.
לי יש את המנייה והקומפני. אני רוצה לדעת האם כדאי לי כרגע לקנות אותה, ולכן אני קורא לפונקציה שאתם מביאים לי, לפי זה מבצע איזשהו חישור, אם לא הייתם מביאים לי לא הייתה לי שום אפשרות לגלות מה המגמה של המניה כרגע.
אז כל מה שנשאר לנו לעשות זה להשתמש עם זה. בואו נחזור לפרוגרם, בפרוגרם אנחנו צריכים לבנות אובייקט מסוג stock market trend, לבנות אובייקט סטוק, לתת לו ערכים ולבדוק האם אנחנו יכולים לקנות אותו או שווה לנו לקנות אותו.
is OK to buy ובואו נקרא לפונקציה שלנו is good to buy וניתן לה עכשיו דלגייט לכתובת המדויקת של הפונקציה. איך אנחנו עושים את זה?
אנחנו צריכים לבנות אובייקט מטיפוס טרנד מנאג'ר, לתת לו את הכתובת של הפונקציה, הכתובת של הפונקציה שלנו הוא טרנדס נקודה גט טרנד, זאת הפונקציה שלנו, ולאחר מכן את פונקצ'ן אדרס להעביר ל-is good to buy.
בואו נדפיס ונראה מה הוא אומר לנו. והוא אומר לנו כרגע false, כנראה בגלל שהיום לא יום ראשון ולא יום שני ולא יום שלישי. טוב, אז מה אנחנו יכולים לקצר פה? דבר ראשון ראינו שאנחנו לא חייבים לבנות אובייקט מלא, אלא פשוט לתת בצורה כזאת את הפונקציה.
בואו נריץ ונראה, קיבלנו את אותו הדבר. דבר שני,