בתכנות, המושגממשק (באנגלית:Software Interface) משמש להפשטה שלמחלקות התוכנה, ומגדיר את הפונקציונליות שעל כל מחלקה לממש כדי להיות שייכת אליו.
אםאובייקט עושה שימוש בממשק כלשהו, אז הדבר מבטיח שלאובייקט תהיה התנהגות מסוימת. מימוש של ממשק הוא התחייבות של אובייקט למלא אחר מפרט של דרישות להתנהגות מסוימת. לפיכך, ניתן לראות בממשקכחוזה. כאשר מחלקה מממשת את כל הפונקציות המוגדרות בממשק ניתן ליצורמופע שלה, אחרת היא נחשבתמימוש אבסטרקטי – כזה שדורש הרחבה על ידי מחלקה אחרת המשלימה את המימוש.
שימוש בממשקים הוא נוהג של כתיבה נכונה בהנדסת תוכנה, כי בשיטה זו מתבצעת הפרדה בין המימוש בפועל לבין הדרישות שמאופיינות בממשק.
מגווןתבניות עיצוב (design patterns) עושות שימוש רב בממשקי תוכנה. ממשק התוכנה חשוב גם בפונקציות הנקראות בצורה מרוחקת (ראוRPC).
מערכות תשתית רבות כמוJava EE,Spring Framework ו-Inversion of control מסייעות באתחולאובייקטים על פי ממשק שמוגדר מראש.
נניח שקיים ממשק ובו שתי התנהגויות (מתודות) שעל כל אובייקט שמקיים את הממשק להכיל. האחת היא מתודה ללא טיפוס החזרה (void) והשנייה היא מתודה בוליאנית. המתודה הראשונה לא מקבלת פרמטרים (מידע) והמתודה השנייה מקבלת פרמטר אחד מסוג int.
כך נראה קטע הקודב-#C של הממשק:
publicinterfaceIdostuff{voidDoThis();boolDoThat(inta);}וזהו קטע קוד של אובייקט שמממש את הממשק, כלומר מכיל שתי מתודות כפי שצוין:
publicclassMyClass:Idostuff{publicvoidDoThis(){Console.WriteLine("I'm doing This");}publicboolDoThat(inta){if(a%2==0){returntrue;}returnfalse;}}אובייקט יכול לממש מספר אינסופי של ממשקים וכך לענות על מספר דרישות. השימוש בממשק יכול לעזור לעקוףעץ ירושה של אובייקטים. למשל, אם קיים אובייקט של Person שיורש מאובייקט Mammals, ואובייקט אחר בשם Table שיורש מאובייקט של SolidItems, אז ניתן באמצעות ממשק ליצור לשני האובייקטים מתודות דומות. כלומר, אין צורך שהאדם יירש תכונות ממחלקת החפצים המוצקים, ולהפך, אין צורך להצהיר שהשולחן יירש תכונות ממחלקת היונקים.
הממשק לא מכתיב כיצד יש לממש את המתודות שהוא דורש. בדוגמה לעיל למשל, אובייקט אחר יכול לממש את המתודה הבוליאנית (מחזירה אמת או שקר) DoThat, בכך שהוא יחזיר אמת כל עוד הפרמטר שונה מאפס למשל. אין אפשרות שממשק יחייב אובייקט להכיל שדות מסוימים (אופן שמירת מידע), אלא רק מתודות (התנהגויות).
- Immutable – ממשק שמבטיח שלא יהיה ניתן לשנות את המידע שאובייקט מכיל בתוכו. דוגמה לאובייקט כזה הוא הטיפוס stringבשפת #C. טיפוס זה מייצג מחרוזת, ומורכב ממערך של תווים. אין אפשרות לגשת לאינדקס של תו מסוים במחרוזת, אינדקס אפס למשל עבור התו הראשון במחרוזת ומשם לשנות את התו.טיפוס נתונים זה ניתן לשרשור (חיבור של מחרוזות) או להשמה מחדש, אבל כאמור אין אפשרות לגשת לתו מסוים במחרוזת ולהחליפו בתו אחר.
- Comparable – ממשק שמבטיח שהאובייקט הוא בר-השוואה יחסית לאובייקטים אחרים מאותו סוג. למשל הטיפוס int מקיים את הממשק, ולפיכך ניתן להשוות ביןמספר שלם אחד למשנהו. הממשק מכיל רק מתודה אחת בשם CompareTo והיא מחזירה אחד משלושה ערכים. אם הערך המוחזר הוא 1- אז האובייקט שמשווה את עצמו לאובייקט אחר כפרמטר – קטן מהאובייקט המושווה. אם הערך שווה לאפס אז שני האובייקטים שווים, ואם הערך הוא 1+ אז האובייקט המשווה גדול מהאובייקט המושווה.
דוגמה לקוד ב-#C:
staticvoidMain(string[]args){inta=3;intb=5;intc=3;Console.WriteLine(a.CompareTo(b));Console.WriteLine(b.CompareTo(a));Console.WriteLine(a.CompareTo(c));Console.ReadLine();}בפקודת ההדפסה הראשונה (Console.WriteLine היא פקודה ב-#C שגורמת לטקסט להיות מוצג על המסך, הדבר מכונה הדפסה אף על פי שלא מדובר בהדפסה של ממש), שואלים למעשה את a אם הוא קטן מ-b. מאחר שהתוצאה היא 1- הכוונה לאמת.
בפקודת ההדפסה השנייה, שואלים את b אם הוא קטן מ-a. מאחר שהתוצאה היא 1 הכוונה לשקר (b נמצא אחרי a על סרגל הצירים).
בפקודת ההדפסה השלישית, שואלים את a אם הוא קטן מ-c. במקרה זה הם שווים ולכן התוצאה היא 0 (אין הכרעה מי יותר גדול).
- NotifyPropertyChanged – ממשק שבא להבטיח שאובייקט יעדכן את הסביבה שלו כאשר שדה כלשהו שלו משתנה. הממשק חשוב לטכנולוגייתWPF ול-Binding. אם לאובייקט יש למשל שדה בשם FirstName והוא מוצמד לשדה טקסט של TextBlock, והאובייקט עונה על חוזה (ממשק) זה, אז ברגע שישתנה השדה שלו גם הטקסט על הפקד ישתנה. במילים פשוטות, שינוי של ערך בזיכרון מעדכן את ממשק המשתמש על השינוי שנעשה בו.