» נושאי לימוד
» נושאי לימוד
יום שני 29 באפריל 2024
מהו ממשק, ולשם מה הוא טוב?
דף ראשי  מתחילים  עוד בנושא ממשקים  מהו ממשק, ולשם מה הוא טוב? גרסה להדפסה

מהו ממשק, ולשם מה הוא טוב?

 

על פי The Java Tutorial by Campione & Walrath:

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

 

ממשקים יהיו שימושיים כדי:

·       ללכוד את הדימיון בין מחלקות שאינן קשורות, מבלי לכפות עליהן קשר מחלקתי.

·       להצהיר על מתודות, שבהן אמורות מחלקות שונות להשתמש.

·       לחשוף את ממשק התכנות של אובייקט, מבלי לחשוף את המחלקה שלו (אובייקטים כאלה נקראים אובייקטים אנונימיים והם שימושיים כאשר אנו שולחים חבילה של מחלקות למְפַתחים אחרים).

 

ממשקים וירושות מרובות

 

++C מאפשרת למתכנת ליצור מחלקה חדשה כתת-מחלקה של שתי מחלקות-על, או יותר.
אנו קוראים לזה ירושות מרובות.

Java אינה מאפשרת ירושות מרובות. ספרים אחדים טוענים שהממשק הוא תחליף לירושות מרובות ב‑Java, אחרים מתנגדים לכך. להלן מה שאומר בעניין זה The Java Tutorial.

לעתים מתייחסים לממשק כחלופה לירושה ממחלקות מרובות.
אף על פי שממשקים עשויים לפתור חלק מאותן הבעיות שאפשר לפתור באמצעות ירושות מרובות,
הם בכל זאת יצורים שונים לחלוטין.
למשל:

·       לא ניתן לרשת משתנים מממשק.

·       לא ניתן לרשת את יישום המתודה מממשק.

·       היררכיית הממשקים היא בלתי תלויה בהיררכיית המחלקות; מחלקות, המשתמשות באותם הממשקים, עשויות להיות קשורות זו לזו בהיררכיית המחלקות, אך עשויות גם להיות בלתי קשורות.

כל אלו אינם נכונים לגבי ירושות מרובות.

 

הגדרת ממשק

 

הגדרת ממשק דומה מאוד להגדרת מחלקה. הגדרת הממשק מורכבת משני חלקים:

·       הצהרה

·       גוף הממשק

 

בצורתו הסכימטית, ממשק עשוי להיראות כך:

 

interfaceDeclaration{
  //interfaceBody
}//end of interface definition

 

interfaceDeclaration מצהירה על תכונות שונות של הממשק
(שם, האם הוא מרחיב ממשק אחר, וכו')

interfaceBody מכיל את הקבועים והצהרות המתודות של הממשק.

 

הצהרה

 

הצהרת ממשק מינימלית מורכבת ממילת המפתח interface ומשֵם הממשק.

כמו לגבי מחלקות, מקובל להתחיל את שם הממשק באות גדולה, אם כי אין זה הכרח.

הצהרת הממשק עשוי להכיל שני רכיבים נוספים:

·         מגדיר הגישה public

·       רשימה של "ממשקי-על".

 

ממשק עשוי להרחיב ממשקים אחרים.

אבל, בניגוד למחלקה, שעשויה להרחיב רק מחלקה אחרת אחת,
ממשק עשוי להרחיב כל מספר של ממשקים אחרים.

 

להלן הגדרה מלאה של ממשק, המורכבת מגוף הממשק ומההצהרה. (בגוף הממשק נדון בהמשך.)

 

public interface MyIntfc extends interfaceX, interfaceY{
  public final double pi = 6.14;
  public final int intConstant = 125;
  void set(int inData);
  int get();
}//end interface MyIntfc

 

מגדיר הגישה public מציין שבממשק תוכל להשתמש כל מחלקה, מכל חבילה.
אם משמיטים אותו, הממשק יהיה נגיש רק למחלקות שהוגדרו בתוך החבילה הנתונה.

הפסוקית extends דומה לזו המופיעה בהצהרת מחלקה.
ממשק יכול להרחיב ממשקים מרובים, בעוד שמחלקה עשויה להרחיב רק מחלקה אחרת אחת.

ממשק אינו יכול להרחיב מחלקות.

רשימת ממשקי-העל היא רשימה מופרדת בפסיקים של שמות כל הממשקים, שאותם מרחיב הממשק החדש.

ממשק יורש ממשק-העל שלו את כל הקבועים והמתודות,
אלא אם כן:

·       הממשק מסתיר קבוע מאחורי קבוע אחר בעל שם זהה.

·       הממשק מצהיר מחדש על מתודה באמצעות הצהרת-מתודה חדשה.

 

גוף הממשק

 

גוף הממשק מכיל הצהרות של מתודות.

הצהרת כל מתודה מסתיימת בנקודה-פסיק, ולא מובא עבורה גוף-מתודה.

מתכנתי ++C יגלו שבאופן עקרוני גוף הממשק זהה לאב-טיפוס של פונקציה.

 

אין להשתמש ב‑transient, volatile, private, protected, synchronized בהצהרה על חבר בממשק.

כל המתודות, המוצהרות בממשק, מצוינות באופן בלתי מפורש כ‑public וכ‑abstract.

 

גוף הממשק עשוי להגדיר גם קבועים. ערכי הקבועים, המוגדרים בממשק, מצוינים באופן בלתי מפורש כ‑public, static ו‑final.

 

דוגמה להגדרה מלאה של ממשק בשם MyIntfc הבאנו למעלה.
הממשק הצהיר על שתי מתודות
get() ו‑set() והגדיר שני קבועים, pi ו‑intConstant.
הממשק ההוא הרחיב את
interfaceX ו‑interfaceY.

 

שימוש בממשק

 

השימוש בממשק נעשה על ידי הגדרת מחלקה אשר משתמשת בממשק על פי שמו.

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

 

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

 

הנה דוגמה למחלקה שמשתמשת בשני ממשקים: Constants ו‑MyIntfc.

 

class ClassA implements Constants,MyIntfc{
  double data;
  
  //Define versions of set() and get() appropriate to 
  // ClassA
  public void set(int inData){
    //note use of pi from Constants interface
    data = (double)inData*pi;
    System.out.println(
      "In set() method for classA, using pi from " +
                           "Constants interface: " + data);
  }//end set()
  
  public int get(){
    return (int)data;
  }//end get()
  
  //Define a show method for ClassA not declared in 
  // interface MyIntfc
  void show(){
    System.out.println(
            "In show() method for ClassA, data = " + data);
  }//end show() method
}//end ClassA
//=======================================================//

 

 

כפי שניתן לראות, המחלקה מספקת הגדרות מלאות של המתודות get() ו‑set(), המוצהרות בממשק MyIntfc, וגם משתמשת בקבועים שהוגדרו בממשק Constants.

נוסף על אלה, המחלקה מספקת גם הגדרה עבור המתודה show(), שאינה מוצהרת באף אחד משני הממשקים.

 

ממשק כטיפוס

 

ההגדרה של ממשק היא הגדרה של טיפוס חדש של נתוני הצבעה. תוכל להשתמש בשם הממשק כמעט במקום כל שם של טיפוס אחר.

ואולם, לא ניתן ליצור אובייקטים מטיפוס הממשק. לממשק אין בנאי.

 

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

 06-01-04 / 19:43  נוצר ע"י רונית רייכמן  בתאריך 
 תוכנית לדוגמא - הקודםהבא - השורה התחתונה בנושא ממשקים 
תגובות הקוראים    תגובות  -  0
דרכונט
מהי מערכת הדרכונט?
אינך מחובר, להתחברות:
דוא"ל
ססמא
נושאי לימוד
חיפוש  |  לא פועל
משלנו  |  לא פועל
גולשים מקוונים: 13