שימוש בממשק בג'אווה - תכנות - HWzone פורומים
עבור לתוכן
  • צור חשבון

שימוש בממשק בג'אווה


yotamoo

Recommended Posts

שלום

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

כעת, לצורך תרגול של ממשק, אני רוצה להוסיף ממשק בשם "צורה" שיגדיר לכל התת-מחלקות איך להתנהג. האם הממשק "צורה" מחליף את מחלקה או בא בנוסף אליה?

תודה

קישור לתוכן
שתף באתרים אחרים

הממשק נועד לזה שתוכל להכריח את מי שממש את הממשק לממש פונקציות מסויימות

(הוא יכול לממש אותם גם באופן רייק,אבל הוא חייב לממש משהו)

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

הפונקציות יודעות שמה שהם מקבלים זה אובייקט שממש את כל הפונקציות שקיימות בממשק

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

על הצורה,לדוגמא את שם הצורה,את השטח שלה,את הצבעים שלהם וכו...

אתה יכול ליצור ממשק שבו אתה מחייב את מי שממש את הממשק להכין עבורך פונקציות מתאימות שיחזירו

את השם של הצורה,את השטח ואת הצבעים

הפונקציה שלך תקבל כפרמטר אובייקט שממש את הממשק,עכשיו היא יודעת בוודאות שיש לה את כל מה שצריך

כדאי להדפיס פרטים על הצורה

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

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

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

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

קישור לתוכן
שתף באתרים אחרים

אוקיי מעולה, אבל הנה משהו שאני לא מבין:

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

כאשר אני משתמש בממשק אני לא חוסך לעצמי שורות קוד מאחר והוא רק מגדיר לי באילו שיטות להשתמש אבל אני עדיין צריך לכתוב אותן (כולל הגוף) במחלקה המממשת. אז אני לא מבין 2 נקודות:

א. כיצד שימוש בממשק עדיף על ירושה, כפי שקראתי במספר מקומות?

ב. כיצד ממשק פותר את הבעיה שבג'אווה ניתן לרשת רק מחלקה אחת?

תודה!

קישור לתוכן
שתף באתרים אחרים

בניגוד לירושה רגילה שמאפשרת למחלקה לרשת אך ורק ממחלקה אחת, מחלקה יכולה לממש כמה ממשקים שהיא רוצה. כלומר, אם יש לך מחלקה בשם B וממשקים בשם F,G ו-H, אז אין שום בעיה לעשות מחלקה שתירש מ-B ותממש את שלושת הממשקים הנ"ל:

public class D extends B implements F,G,H

זה אמור לענות לך על שתי השאלות.

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

כעת, יש לך פונקציה כלשהי שמקבלת אובייקט (תיכף נקבע מה יהיה הטיפוס שלו) ומשנה את הצבע שלו לאדום. מה צריך להיות הטיפוס של האובייקט הזה? אם תקבע אותו להיות "צורה", אז לא תוכל להעביר לפונקציה שום אובייקט מטיפוס "אות". באותו אופן גם לא תוכל לקבוע שיהיה מטיפוס "אות". תוכל לכתוב שתי פונקציות נפרדות - אחת שמקבלת "צורה" ואחת שמקבלת "אות", אבל זה שכפול קוד, וכל פעם שתרצה להוסיף אובייקט חדש עם פונקציות setColor/getColor תצטרך להוסיף טיפול מיוחד גם בו.

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

ממשק למעשה פותר לך את הבעיה הזו. תגדיר ממשק שנקרא "צבעוני", ומוגדרות בו המתודות setColor/getColor. האובייקט "צורה" ו-"אות" יממשו את הממשק הזה. כעת, הפונקציה יכולה לקבל אובייקט מטיפוס "צבעוני" ואז היא תהיה מסוגלת להתמודד עם כל אובייקט שמממש את הממשק הזה.

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

קישור לתוכן
שתף באתרים אחרים

על שאלה א' אני יוכל לענות לך כי זה יותר קשור לתכנות OO בכללי:

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

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

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

שניצל הקדים אותי

קישור לתוכן
שתף באתרים אחרים

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

ממשק כזה נקרא marker interface ולרוב הוא אינו מכיל אף הגדרה של מתודה

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

זה אותו דבר כמו אנוטציה (כנראה השתמשו בזה לפני שהמציאו את האנוטציות)

קישור לתוכן
שתף באתרים אחרים

צודק, אבל זה באמת שימוש נדיר יחסית (וכמו שאמרת, הוא הוחלף באנוטציות).

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

http://en.wikipedia.org/wiki/Dependency_injection

קישור לתוכן
שתף באתרים אחרים

ארכיון

דיון זה הועבר לארכיון ולא ניתן להוסיף בו תגובות חדשות.

×
  • צור חדש...