ההבחנה בין מחלקה מופשטת וממשק ב-Java

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

ההבחנה בין מחלקה מופשטת לבין ממשק

  1. abstract משמש ליצירת מחלקה מופשטת וניתן להשתמש בו גם עם שיטות, בעוד שמילת המפתח interface משמשת ליצירת ממשק ואינה יכולה לשמש עם שיטות.
  2. מחלקות משנה משתמשות במילת המפתח extends כדי להרחיב מחלקה מופשטת ועליהן לספק מימוש לכל השיטות המוכרזות במחלקה מופשטת, אלא אם כן המחלקה המשנה היא גם מחלקה מופשטת. לעומתן, מחלקות משנה משתמשות במילת המפתח implements כדי לממש ממשקים ועליהן לספק מימוש לכל השיטות המוכרזות בממשק.
  3. אבסטרקטיות יכולות להכיל שיטות עם מימוש, בעוד שאינטרפייס מספקת הפרדה מוחלטת ואינה יכולה לכלול מימוש של שיטה. שים לב שמהגרסה 8 של ג'אווה והלאה, ניתן ליצור שיטות ברירת מחדל וסטטיות באינטרפייס המכילות מימוש של השיטות.
  4. אבסטרקטיות יכולות להכיל בנאי, בעוד שאינטרפייס לא יכולות לכלול בנאי.
  5. מחלקה אבסטרקטית מכילה את כל התכונות של מחלקה רגילה בג'אווה, רק שלא ניתן ליצור אותה באמצעות השמה לאובייקט. ניתן להשתמש במילת המפתח `abstract` כדי להגדיר מחלקה כאבסטרקטית, אך אינטרפייס הם סוג שונה לחלוטין שיכול לכלול רק קבועים סטטיים פומביים והכרזות של שיטות.
  6. שיטות במחלקות אבסטרקטיות יכולות להכיל מזההי גישה כמו public, private, protected, static, אולם שיטות באינטרפייס פומביות ומופשטות מראש, ואי אפשר להשתמש בכל סוג אחר של מזהה גישה.
  7. A subclass can extend only one abstract class but it can implement multiple interfaces.
  8. מחלקות אבסטרקטיות יכולות להרחיב מחלקה אחרת ולהממש אינטרפייסים, אך אינטרפייס יכול להרחיב רק אינטרפייסים אחרים.
  9. ניתן להריץ מחלקה אבסטרקטית אם יש לה את המתודה `main()`, אך אינטרפייס אינן יכולות להכיל מימוש של המתודה main ולכן אין אפשרות להריץ אותן.
  10. המטרה העיקרית של אינטרפייס היא להגדיר חוזה למחלקות המשתמשות בה, בעוד שמחלקה אבסטרקטית יכולה גם להגדיר חוזה, אך יכולה גם לספק מימושים לשיטות שמחלקות מקוננות יכולות להשתמש בהם.

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

ממשק או מחלקה אבסטרקטית

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

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

השתמש במחלקות מופשטות וממשקים גם

שימוש בממשקים ובמחלקות מופשטות ביחד הוא הגישה הטובה ביותר לעיצוב מערכת. לדוגמה, ב-JDK java.util.List הוא ממשק שמכיל הרבה שיטות, לכן קיימת מחלקה מופשטת java.util.AbstractList שמספקת יישום סקלטי לכל השיטות של ממשק ה-List, כך שכל תת-מחלקה יכולה להרחיב את המחלקה הזו ולממש רק את השיטות הנדרשות. כדאי תמיד להתחיל עם ממשק כבסיס ולהגדיר שיטות שכל תת-מחלקה צריכה לממש ואז אם ישנם שיטות שרק תת-מחלקה מסוימת צריכה לממש, אפשר להרחיב את ממשק הבסיס וליצור ממשק חדש עם השיטות הללו. לתת-מחלקות יש את האפשרות לבחור בין הממשק הבסיסי או הממשק הילד לממש לפי דרישותיהן. אם מספר השיטות גדל מאוד, זהו לא רעיון רע לספק מחלקה מופשטת סקלטית המממשת את ממשק הילד ומספקת גמישות לתת-מחלקות לבחור בין ממשק ומחלקה מופשטת.

שינויים בממשק ב-Java 8

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

Source:
https://www.digitalocean.com/community/tutorials/difference-between-abstract-class-and-interface-in-java