ממשק (תכנות) – הבדלי גרסאות

מתוך ויקיפדיה, האנציקלופדיה החופשית
תוכן שנמחק תוכן שנוסף
Delta739 (שיחה | תרומות)
Delta739 (שיחה | תרומות)
שורה 61: שורה 61:
בפקודת ההדפסה השנייה, שואלים את b אם הוא קטן מ-a. מאחר והתוצאה היא 1 הכוונה לשקר (b נמצא אחרי a).{{ש}}
בפקודת ההדפסה השנייה, שואלים את b אם הוא קטן מ-a. מאחר והתוצאה היא 1 הכוונה לשקר (b נמצא אחרי a).{{ש}}
בפקודה ההדפסה השנייה, שואלים את a אם הוא קטן מ-c. במקרה זה הם שווים ולכן התוצאה היא 0.
בפקודה ההדפסה השנייה, שואלים את a אם הוא קטן מ-c. במקרה זה הם שווים ולכן התוצאה היא 0.
* INotifyPropertyChanged - ממשק שבא להבטיח שאובייקט יעדכן את הסביבה שלו כאשר שדה כלשהו שלו משתנה. הממשק חשוב לטכנולוגיית WPF ול-Binding. אם לאובייקט יש למשל שדה בשם FirstName והוא מוצמד לשדה טקסט של TextBlock, והאובייקט עונה על חוזה (ממשק) זה, אז ברגע שישתנה השדה שלו גם הטקסט על הפקד ישתנה. במילים פשוטות, שינוי של ערך בזיכרון מעדכן את ממשק המשתמש על השינוי שנעשה בו.
* '''INotifyPropertyChanged''' - ממשק שבא להבטיח שאובייקט יעדכן את הסביבה שלו כאשר שדה כלשהו שלו משתנה. הממשק חשוב לטכנולוגיית WPF ול-Binding. אם לאובייקט יש למשל שדה בשם FirstName והוא מוצמד לשדה טקסט של TextBlock, והאובייקט עונה על חוזה (ממשק) זה, אז ברגע שישתנה השדה שלו גם הטקסט על הפקד ישתנה. במילים פשוטות, שינוי של ערך בזיכרון מעדכן את ממשק המשתמש על השינוי שנעשה בו.





גרסה מ־04:51, 28 באוגוסט 2013

בתכנות, המושג ממשקאנגלית: Software Interface) משמש לאבסטרקציה של מחלקות התוכנה, ומגדיר את הפונקציות שעל מחלקה לממש כדי להיות שייכת אליו. במילים אחרות, אם אובייקט מממש ממשק כלשהו, אז הדבר מבטיח שלאובייקט תהיה התנהגות מסוימת. מימוש של ממשק הוא התחייבות של אובייקט למלא אחר מפרט של דרישות להתנהגות מסוימת, ניתן לראות בממשק כחוזה. כאשר מחלקה מממשת את כל הפונקציות המוגדרות בממשק ניתן ליצור מופע שלה, אחרת היא נחשבת מימוש אבסטרקטי - כזה שדורש הרחבה על ידי מחלקה אחרת המשלימה את המימוש. שימוש בממשקים הוא נוהג של כתיבה נכונה בהנדסת תוכנה, כי בשיטה זו מתבצעת הפרדה בין המימוש בפועל לבין הדרישות שמאופיינות בממשק.

מגוון תבניות עיצוב (design patterns) עושות שימוש רב בממשקי תוכנה. ממשק התוכנה חשוב גם בפונקציות הנקראות בצורה מרוחקת (ראו RPC).

מערכות תשתית רבות כמו Java EE,‏ Spring Framework ו-Inversion of control מסייעות באתחול אובייקטים על פי ממשק שמוגדר מראש.

דוגמת קוד

נניח שקיים ממשק ובו שתי התנהגויות (מטודות) שעל כל אובייקט שמקים את הממשק להכיל. האחת היא מטודה ללא טיפוס החזרה (Void) והשנייה היא מטודה בוליאנית. המטודה הראשונה לא מקבלת פרמטרים (מידע) והמטודה השנייה מקבלת פרמטר אחד מסוג int.

כך נראה קטע הקוד ב-C# של הממשק:

 public interface Idostuff
    {
        void DoThis();
        bool DoThat(int a);
    }

וזהו קטע קוד של אובייקט שממש את הממשק, כלומר מכיל שתי מטודות כפי שצויין:

public class MyClass: Idostuff
    {
        public void DoThis()
        {
            Console.WriteLine("I'm doing This");
        }

        public bool DoThat(int a)
        {
            if (a % 2 == 0)
                return true;
            return false;
        }
    }

הקונבנציה (המוסכמה בתחום) בעולם התוכנה היא שממשק תמיד יתחיל באות I, ולאחר מכן תיאור של החוזה. לדוגמה: ICanRead, ICanLearn וכו'. לאובייקטים שיממשו את החוזה יהיה מטודות בלי התחילת I, למשל CanRead ו-CanLearn.

אובייקט יכול לממשק מספר אינסופי של ממשקים וכך לענות על מספר דרישות. השימוש בממשק יכול לעזור לעקוף עץ ירושה של אובייקטים. למשל, אם קיים אובייקט של Person שיורש מאובייקט Mammls, ואובייקט אחר בשם Table שיורש מאובייקט של SolidItems, אז ניתן באמצעות ממשק ליצור לשני האובייקטים מטודות דומות. כלומר, אין צורך שהאדם יירש תכונות ממחלקת החפצים המוצקים, ולהיפך, אין צורך להצהיר שהשולחן יירש תכונות ממחלקת היונקים.

הממשק לא מכתיב כיצד יש לממש את המטודות שהוא דורש. בדוגמה לעיל למשל, אובייקט אחר יכול למממש את המטודה הבוליאנית (מחזירה אמת או שקר) Dothat, בכך שהוא יחזיר אמת כל עוד הפרמטר שונה מאפס למשל. אין אפשרות שממשק יחייב אובייקט להכיל שדות מסוימים, אלא רק מטודות.

ממשקים נפוצים

  • IImmutable - ממשק שבה להבטיח שלא יהיה ניתן לשנות את המידע שאובייקט מכיל בתוכו. דוגמה לאובייקט כזה הוא הטיפוס String בשפת C#. טיפוס זה מייצג מילה, ומורכב ממערך של אותיות. אין אפשרות לגשת לאינדקס של אות מסוימת במילה, אינדקס אפס למשל עבור האות הראשונה במילה, ומשם לשנות את האות. טיפוס נתונים זה ניתן לשרשור (חיבור של מילים) או להשמה מחדש, אבל כאמור אין אפשרות לגשת לאות מסוימת במילה ולהחליפה באות אחרת.
  • IComparable - ממשק שמבטיח שהאובייקט הוא בר-השוואה יחסית לאובייקטים אחרים מאותו סוג. למשל הטיפוס int מקיים את הממשק, ולפיכך ניתן להשוות בין מספר שלם אחד למשנהו. הממשק מכיל רק מטודה אחת בשם CompareTo והיא מחזירה אחד משלושה ערכים. אם הערך המוחזר הוא 1- אז האובייקט שמשווה את עצמו לאובייקט אחר כפרמטר - קטן מהאובייקט המושווה. אם הערך שווה לאפס אז שני האובייקטים שווים, ואם הערך הוא 1+ אז המצב ההפוך מהמצב הראשון מתקיים.

דוגמה לקוד ב-C#:

static void Main(string[] args)
        {
            int a = 3;
            int b = 5;
            int c = 3;

            Console.WriteLine(a.CompareTo(b));
            Console.WriteLine(b.CompareTo(a));
            Console.WriteLine(a.CompareTo(c));
            Console.ReadLine();
        }

בפקודת ההדפסה הראשונה, שואלים למעשה את a אם הוא קטן מ-b. מאחר והתוצאה היא 1- הכוונה לאמת.
בפקודת ההדפסה השנייה, שואלים את b אם הוא קטן מ-a. מאחר והתוצאה היא 1 הכוונה לשקר (b נמצא אחרי a).
בפקודה ההדפסה השנייה, שואלים את a אם הוא קטן מ-c. במקרה זה הם שווים ולכן התוצאה היא 0.

  • INotifyPropertyChanged - ממשק שבא להבטיח שאובייקט יעדכן את הסביבה שלו כאשר שדה כלשהו שלו משתנה. הממשק חשוב לטכנולוגיית WPF ול-Binding. אם לאובייקט יש למשל שדה בשם FirstName והוא מוצמד לשדה טקסט של TextBlock, והאובייקט עונה על חוזה (ממשק) זה, אז ברגע שישתנה השדה שלו גם הטקסט על הפקד ישתנה. במילים פשוטות, שינוי של ערך בזיכרון מעדכן את ממשק המשתמש על השינוי שנעשה בו.