יוםראשון, 02 ליולי 2014 סמסטר סוף מבחן )236703( עצמים מונחה תכנות - א' מועד 2014, אביב סמסטר קמחי יחיאל ד"ר מרצה: מסינג מיטל עבדאלקאדר, כרם גלעד, ערן מתרגלים: הנחיות: השאלות. כל על לענות עליכם משקל. שוות שאלות 5 במבחן מהנקודות. 20% ותקבלו יודע/ת" "לא כתבו התשובה את יודעים אינכם אם סעיף, בכל הקוד כי ייתכן אחרת במפורש נאמר לא אם הקוד, פלט את לציין נדרש בה שאלה בכל הריצה זמן או הקומפילציה שגיאת את לציין יש כזה במקרה רץ. או מתקמפל לא מתרחשת. היא מדוע ולהסביר התשובה. על הניתן בציון תפגע נכון( הוא אם )אף בעליל רלוונטי לא מידע הוספת לעניין. ענו קריאות. בלתי תשובות לבדוק אפשר אי ברור. בכתב תשובתכם כתבו חדש. בעמוד תשובה כל התחילו עזר. חומר בכל להשתמש אין כולם. את שקיבלתם כעת ודאו זה(. עמוד )כולל עמודים 8 במבחן שעות. שלוש הבחינה משך.5.7.6.8.9 בהצלחה! 8 מתוך 1 עמוד 127602 עצמים מונחה תכנות 1024 אביב
שאלה 1: פולימורפיזם הכלה polymorphism( )inclusion השאלה הזו עוסקת בנושא הפולימורפיזם - אבל מתרכזת בפולימורפיזם ההכלה. כל התייחסות לסוג אחר של רבגוניות צריך להיות רלוונטי באופן ישיר לשאלה ומנומק. אנו מזכירים לכם כי פולימורפיזם ההכלה ממומש בעזרת יחסי הורשה ו- binding.dynamic השאלה עוסקת במשמעויות של פולימורפיזם ההכלה לגבי התנהגות התוכנה וכן עוסקת בדרכים השונות למימוש תכונה זו כפי שהדבר מתבטא בשפות שונות לתכנות מונחה עצמים. בכל השאלה הזאת, כשכתוב פולימורפיזם אנו מתכוונים ל בפולימורפיזם ההכלה. לכל הסעיפים שלהלן יש תשובות קצרות - תשובות ארוכות עלולות להפסיד נקודות. )2 נק'( תנו דוגמת קוד קצרה שמראה שהקוד הבא מתנהג בצורה פולימורפית: int f(y &y) { return y.g(); )2 נק'( מדוע דוגמת הקוד הקצרה הבאה אינה מתנהגת בצורה פולימורפית? הסבירו את הבעיה: int f(const Y y) { return y.g(); )6 נק'( נניח שבשפת ++C נבטל את תכונת העברת ארגומנטים by-reference לדוגמא ונשאיר רק את צורות העברת הפרמטרים הקיימות ב- C. )int )n& א. האם זה יבטל לחלוטין את האפשרות לספק קוד רבגוני או יגרום לשינוי משמעותי בסגנון התכנות? נמקו במדויק מדוע כן או מדוע לא. ב. מהי היכולת )תכונה( של ++C שתיפ גע באופן החמור ביותר מחוסר?reference )הכוונה היא שאין שום דרך לעקוף את הקושי( )6 נק'( בהרצאה נתקלנו בכמה סוגים של דריסות (Overriding/Refinement) דרכים לניהול\שליטה על מנגנון הקישוריות הדינאמית binding).(dynamic תנו דוגמה לשני סוגי דריסה. עבור כל אחד משני הסוגים: א. תנו הסבר קצר המייחד את הסוג הזה לעומת האחר. ב. תנו שתי דוגמאות למימושים שונים )ייתכן בשפות שונות( של הסוג המדובר )אינכם חייבים להוכיח בקיאות בשפות שלא נלמדו במהלך הקורס(. עמוד 2 מתוך 8
שאלה הקוד 2: שימוש בתכנות מונחה עצמים להקטנת סיבוכיות לפרדיגמה של תכנות מונחה עצמים יש יתרונות רבים )בלי לזלזל ביתרונות של פרדיגמות אחרות(. אחד הדברים שראינו בהרצאה היה "שימוש בתכנות מונחה עצמים להקטנת סיבוכיות הקוד" כאשר "סיבוכיות הקוד" יכולה להתפרש בכמה צורות: חסכון בכתיבת קוד ע"י המתכנת מניעת שכפול קוד שנעשה ע"י המהדר )הקומפיילר( אפשרויות נוספות השאלות: )22 נק'( הציגו שתי דוגמאות שונות באופן מהותי, המדגימות את התופעה ומסבירות בדיוק כיצד משתמשים בתכונות המאפיינות את התכנות מונחה העצמים כדי לממש את הדוגמאות )איננו טוענים שאי-אפשר לפתור את הבעיות תוך שימוש בפרדיגמות תכנות אחרות(. הסבירו כל דוגמה ונמקו כיצד מוקטנת סיבוכיות הקוד. )6 נק'( הסבירו מדוע הדוגמה "שימוש בהורשה כדי למנוע שכפול קוד של מחלקת הבסיס" נדחית על הסף. הערה: כל הדוגמאות יכולות להיות ממומשות בשפות שונות, לפעמים בטכניקות קצת שונות, בהתאם ליכולות המיוחדות של כל שפה )++C Python,,D,#C Java, וכולי(. עמוד 3 מתוך 8
C# - שאלה 3 חלק ראשון - return Yield נתון הקוד הבא: class C1 { int F1() { yield return 1; public void Q1() { Console.WriteLine( F1() ); F1(); )4 נק'( האם הקוד C1().Q1() new מתקמפל? אם כן, האם הוא זורק חריגה? אם לא, מהו הפלט שלו? class C2 { int i = 0; IEnumerable<int> F23() { i++; for (int j = 0; j < 10; j++) yield return j; public void Q2() { i = 0; for (int k = 0; k < 10; k++) F23().First(); // access the first element // the semantics of First are not important! Console.WriteLine(i); public void Q3() { i = 0; foreach (int m in F23()) ; Console.WriteLine(i); נתון הקוד הבא: )4 נק'( התעלם מהמתודה Q3. האם הקוד C2().Q2() new מתקמפל? אם כן, האם הוא זורק חריגה? אם לא, מהו הפלט שלו? )4 נק'( התעלם מהמתודה Q2. האם הקוד C2().Q3() new מתקמפל? אם כן, האם הוא זורק חריגה? אם לא, מהו הפלט שלו? המשך השאלה בעמוד הבא עמוד 4 מתוך 8
)המשך שאלה 3( חלק שני - Contra-variance Covariance and )4 נק'( אחת הסיבות לכך שלא ניתן להגדיר מחלקות גנריות קו-וריאנטיות )<T )class C<out או קונטרה-וריאנטיות )<T )class C<in היא האפשרות להגדיר שדות לא-פרטיים, שיהיו נגישים לקריאה ולכתיבה. האם ניתן להגדיר Properties בממשק גנרי קו-וריאנטי או קונטרה-וריאנטי? אם כן, האם יש מגבלות על הצהרת ה- Property? פרט. )4 נק'( נתון הקוד הבא: interface Iface<T> { class Cls<T> : Iface<T> { class Base { class Derived : Base {.5 האם ניתן לשנות את הגדרות המחלקה Cls או הממשק Iface כך שהקוד הבא יעבור קומפילציה? Iface<Derived> d = new Cls<Base>(); הסבר. עמוד 5 מתוך 8
Java generics - שאלה 4 נתונות שלוש מחלקות לא אבסטרקטיות B A, ו- C. נתון כי C יורשת מ- B, שיורשת מ- A. לשלוש המחלקות ישנו בנאי חסר פרמטרים. נתונה המתודה הסטטית copy הבאה: public static void copy( (1) src, (2) dst) { for (int i = 0; i < src.length; i++) { // copy from src to dst dst (3) = src (4) ; public static void main() { (5) src = new (6) ; (7) dst = new (8) ; src (9) = new A(); copy(src, dst); )5 נק'( השלם את הקוד הכתוב למעלה כך שהקוד יתקמפל אבל יזרוק חריגה בזמן ריצה )בלי לזרוק חריגה בצורה ישירה(. הסבר איזה תכונה של שפת Java מאפשרת שהקוד יתקמפל, מדוע תכונה זו נחשבת בעייתית. )6 נק'( נתונה המתודה :copy2 public static void copy2(list< (1) > src, List< (2) > dst) { for ( (3) element : src) { dst.add(element); השלם את המתודה copy2 כך שהקוד הנ"ל לא יתקמפל: List<A> listofas = new ArrayList<A>(); List<B> listofbs = new ArrayList<B>(); copy2 (listofas, listofbs); List<A> listofas = new ArrayList<A>(); List<B> listofbs = new ArrayList<B>(); List<C> listofcs = new ArrayList<C>(); copy2 (listofbs, listofbs); copy2 (listofbs, listofas); copy2 (listofcs, listofbs); copy2 (listofcs, listofas); אך הקוד הנ"ל כן יתקמפל: הסבר מדוע ההשלמה שבצעת למתודה copy2 גורמת לקטע הקוד הראשון לא להתקמפל ולשני כן להתקמפל. רמז: השתמשו בתו? ובמילים super ו\או.extends המשך השאלה בעמוד הבא עמוד 6 מתוך 8
)המשך שאלה 4( )2 נק'( הסבר מה היא פעולת,type erasure וציין באיזה שלב היא מבוצעת. )3 נק'( ציין מדוע למרות שמתקיים ה- erasure,type לקוד שמשתמש ב- generics יש יתרון על קוד דומה שמתבסס על ירושה )למשל,ListA שהיא רשימה לא גנרית, שיכולה להחזיק כל אובייקט מטיפוס B A, ו- C (. )4 נק'( כתבו את הקוד השקול לזה שייצר המהדר עבור המתודה copy2 בסעיף 1, לאחר ביצוע.type erasure.5 עמוד 7 מתוך 8
Squeak - שאלה 5 נתון הקוד הבא: 1 o := #(Prediction is very difficult, especially about the future). "array of symbols" 2 a := o select: [:s s size > 2]. 3 i := 1. 4 b1 := [Transcript show: i]. 5 b2 := [a at: i put: o. o := o class. i := i + 1.]. 6 [o class class ~~ o] whiletrue: b2. 7 c := a deepcopy. "copy array elements recursively" 8 b1 value. הסעיפים הבאים הם בלתי תלויים. )4 נק'( מה יהיה פלט התוכנית? Transcript show: ((a at: 1) == (c at: 1)). Transcript show: ((a at: 2) == (c at: 2)). a := o. (a at: ) superclass new. )4 נק'( מחליפים את שורה 8 בשורה הבאה: מה יהיה פלט התוכנית כעת? )4 נק'( מחליפים את שורה 8 בשורה הבאה: מה יהיה פלט התוכנית כעת? )4 נק'( מחליפים את שורה 1 בשורה הבאה: מה יהיה פלט התוכנית כעת? )4 נק'( מחליפים את שורה 8 בשורה הבאה:.5 השלימו את השורה במקום החסר, כך שהקוד ירוץ ללא שגיאות. עמוד 8 מתוך 8