שאלת מבחן בתכנות מונחה עצמים - אוניברסיטת בר-אילן 2019 - ירושה

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

העתק שאלה
שתף שאלה
סמן כחשוב
סמן כבוצע
אוניברסיטת בר-אילןמועד ב2019סמסטר ב
ירושהפולימורפיזםOverridingמעקב אחר קוד
שימו לב למשמעות שמות המחלקות. האם תת-המחלקה באמת מהווה התמחות או מקרה פרטי של מחלקת-העל, או שהיא משנה את אחת מהתכונות המהותיות המובטחות על-ידי מחלקת-העל?
העיקרון המופר הוא עקרון ההחלפה של ליסקוב (Liskov Substitution Principle - LSP).
עיקרון זה, המהווה נדבך מרכזי בשימוש נכון בירושה ופולימורפיזם, קובע שאובייקטים של מחלקת-על צריכים להיות ניתנים להחלפה באובייקטים של תת-מחלקה שלה, מבלי לשנות את נכונות או התנהגות התוכנית. במילים אחרות, תת-מחלקה צריכה לשמר את החוזה וההתנהגות המצופה ממחלקת-העל שלה.


במקרה זה, המחלקה IterMultiplier יורשת מ-RecursionMultiplier. שם המחלקה RecursionMultiplier מהווה חלק מהחוזה שלה עם המשתמש - הוא רומז באופן מפורש שהפעולה mult ממומשת באמצעות רקורסיה.


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


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


היחס "is-a" (הבסיס לירושה) אינו מתקיים מבחינה סמנטית: IterMultiplier אינו "סוג של" RecursionMultiplier, אלא מימוש אלטרנטיבי לאותה בעיה. עיצוב נכון יותר היה להגדיר ממשק Multiplier ושתי מחלקות נפרדות (RecursionMultiplier ו-IterMultiplier) המממשות אותו.