Abstract Class vs Interface

ההבדל המרכזי בין abstract class לבין interface מתבטא במטרה התכנונית שלהם: abstract class מייצגת קשר מסוג IS-A: משמש ליצירת היררכיה ומשפחה. למשל, Dog הוא Animal. הם חולקים DNA משותף (קוד, שדות, לוגיקה). אם יש לנו קוד אמיתי שאנחנו רוצים שכל הילדים יירשו קומפלט, מחלקה אבסטרקטית היא הפתרון.

בעוד שinterface מייצג קשר מסוג CAN-DO / HAS-A Capability משמש להוספת יכולות חוצות משפחות. למשל, Car יכול להיות Flyable וגם Electric, וגם Duck יכול להיות Flyable. אין קשר משפחתי בין מכונית לברווז, אבל לשניהם יש את היכולת לעוף. ממשקים מאפשרים גמישות מוחלטת שלא תלויה בהיררכיית הירושה.

יתרונות וחסרונות

Abstract Class

יתרונות:

חסרונות:

Interface

יתרונות:

חסרונות:

השוואה בין Abstract Class ל-Interface

תכונה Abstract Class Interface
ירושה (Inheritance) תומכת בירושה בודדת בלבד (מחלקת-בת יכולה לרשת מחלקה אבסטרקטיבית אחת). תומכת בריבוי ממשקים (מחלקה יכולה לממש כמה ממשקים במקביל).
מצב (State / Fields) יכולה להכיל משתני מופע (Fields) עם כל רמת נגישות (private, protected, public). לרוב מכילה רק קבועים (public static final). לא יכולה להחזיק משתני מצב משתנים (Instance fields).
קונסטרוקטורים יכולה להכיל קונסטרוקטור שמופעל באמצעות super() מתוך מחלקות הבת. אין לה קונסטרוקטורים כלל (אי אפשר לאתחל אותה ישירות לא ניתן לקרוא ל NEW).
סוגי מתודות יכולה להכיל מתודות אבסטרקטיות (ללא גוף) וגם מתודות מוגמרות עם מימוש מלא. באופן מסורתי הכילה רק חתימות מתודות; החל מגרסאות מתקדמות (כמו Java 8 ) מאפשרת מתודות ברירת מחדל (default) ומתודות סטטיות.
הוספת מתודה אם נרצה להוסיף מתודה רגילה (עם גוף) ל-Abstract Class בעתיד, נוכל לעשות זאת בקלות וכל מחלקות הבת יקבלו אותה מיד בלי שום בעיה. הוספת מתודה לInterface מסוכנת יותר (או דרשה שינויים): היסטורית, אם הוספת מתודה ל-Interface, כל המחלקות שממשות אותו נשברו בקומפילציה כי הן חייבות לממש גם אותה. לכן הציגו ב-Java 8 את ה-default methods כדי לאפשר הוספת מתודות לממשקים קיימים בלי לשבור את הקוד הישן.

מתי לבחור במה? (כלל אצבע פרקטי)

בחרנו ב-Interface כש:

בחרנו ב-Abstract Class כש:

🏠 Back to Orly's Code Corner