תאריך הבחינה: 24.7.2016. שמות המרצים: ד"ר עזאם מרעי שם הקורס: עקרונות תכנות מונחה עצמים מספר הקורס: 202-15181 שנה: 2016 סמסטר: ב' מועד: א' משך הבחינה: שלוש שעות חומר עזר: אסור מבחן סיכום לקורס " עקרונות תכנות מונחה עצמים " הנחיות כלליות: ההוראות במבחן מנוסחות בלשון זכר, אך מכוונות לנבחנים ולנבחנות כאחד. נא לוודא כי בשאלון זה 15 עמודים. יש לענות על כל השאלות בגוף המבחן בלבד. אין לחרוג מהמקום המוקצה )במקרים חריגים יש לבקש אישור ממרצה\מתרגל(. מומלץ להשתמש במחברת הבחינה כטיוטא. בשאלות רב-ברירה )"אמריקאיות"( יש לסמן תשובה אחת, אלא אם צוין אחרת בגוף השאלה. בשאלות רב-ברירה בהן לא נידרש לנמק, ניתן לסמן תשובה ללא נימוק, אך ניתן גם לספק נימוק קצר, אם רצונכם בכך )חובה לתת נימוק רק בשאלות בהן זה מצוין מפורשות בשאלה(. במידה ואין ניקוד על הסעיפים, כל סעיף מקבל מספר שווה של נקודות )הניקוד לכל השאלה מחולק למספר הסעיפים(. הקוד כתוב בשפת,Java פרט לשאלות בהן מצוין אחרת. אם אינך יודע את התשובה, ניתן לכתוב "לא יודע" ולקבל 20% מהניקוד על הסעיף\השאלה. )1 )2 )3 )4 )5 )6 )7 )8
שאלה ]6 1 נק'[ סמן איזה סוג של קשר יש בין כל זוג מחלקות )קשר רגיל, קשר הרכבה או קשר של היררכיה( זוג מחלקות מאמן / קבוצת כדור-רגל מנהל מחלקה / מחלקה מסלול בגרף / צלע בגרף ספר / פרק הזמנה / הזמנה טלפונית הזמנה / פריט הזמנה קשר רגיל / הרכבה / היררכיה רגיל / הרכבה / היררכיה רגיל / הרכבה / היררכיה רגיל / הרכבה / היררכיה רגיל / הרכבה / היררכיה רגיל / הרכבה / היררכיה שאלה ]10 2 נק'[ בשאלה זו אתם מתבקשים להשלים את תרשים המחלקות הבא Diagram( )Class שמתאר באופן חלקי אתר להזרמת מדיה )לדוגמא סרטים(. האתר מחזיק מנויים. מנוי יכול לבחור תוכנית התחברות מבין שתי תוכניות: רגילה, ומתקדמת. מנוי יכול לבצע הזמנה. הזמנה מורכבת משורות הזמנה. כל שורת הזמנה מתאימה לכותרת אחת. תשלום להזמנה יכול להתבצע דרך שני אמצעי תשלום: אשראי או.PayPal 2
שאלה ]3 3 נק'[ מחלקה )Class( מספקת כמה יכולות חשובות. Service View היא אחת מהן. ציין עוד שתי יכולות והסבר את שלושתן: :Service View.1.2.3 שאלה ]2 4 נק'[ ציין שני הבדלים בין פרוצדורה (procedure) בתכנות פרוצדוראלי לבין הודעה (message) בתכנות מונחה עצמים:.1.2 שאלה ]6 5 נק'[ עיין בקוד הבא 1 class A { 2 public void foo(){ 3 A a = new A(); 4 //a.goo(); 5 this.goo(); 6 7 8 private void goo() { 9 System.out.println("I am in A"); 3
10 public class A1 extends A{ 11 12 public void goo() { 13 System.out.println("I am in A1"); 14 15 ענה על השאלות הבאות רינה טענה שהורדת ההערה בשורה 4 במחלקה A תגרום לשגיאת קומפילציה בגלל שהשיטה goo מוגדרת כ-.private האם טענה זו נכונה? הסבר את תשובתך מה הפלט אחרי הרצת שורות הקוד הבאות? הסבר את תשובתך.1.2 A a = new A1(); a.foo(); רינה עדכנה את הקוד בשתי המחלקות: במחלקה A השיטה goo הפכה ל public בעוד במחלקה A1 הפכה ל.private שורות ההפעלה הן אותן שורות מסעיף 2. בחר את התשובה הנכונה: השיטה goo הקוד לא יתקמפל, שכן אי אפשר להגביל את ההרשאות בתת המחלקה אלא רק להרחיבן )הרי מופע א. של A1 אמור לגשת לכל השירותים שמספק לו A( הקוד יתקמפל. יודפס I am in A ב. הקוד יתקמפל. יודפס I am in B ג. הקוד יתקמפל אך תתבצע שגיאה בזמן ריצה. ד..3 שאלה ]7 6 נק'[ )2 נק'( בשפת Java אין הורשה מרובה. אפשר לספק פתרון אלטרנטיבי להורשה מרובה דרך שימוש ב: 1. Substitution א. Overriding ב. (delegation) Composition ג. Overloading ד. 4
)5 נק'( ציירו תרשים מחלקות ובו אתם מסמלצים את הקוד הבא.2 class A { public void foo() {... class B { public void goo() {... class C extends A, B { // Not allowed in Java! 5
שאלה ]8 7 נק'[ סטודנט בנה תוכנה עם GUI המשתמשת בספריית Swing של Java )עליה למדתן בתרגולים(. בתוכנה של הסטודנט קיימת אנימציה שמזיזה כדור לאורך המסך. מצורף חלק מקוד הסטודנט: public class Car extends JPanel implements ActionListener{ private Timer timer; private int ball_x; private int ball_y; public Car(){ timer = new Timer(200,this); ball_x = 0; ball_y = 50; timer.start(); public void actionperformed(actionevent e){ if (e.getsource() == timer){ ball_x = (ball_x + 5) % getsize().width; repaint(); public void paint(graphics g){ super.paint(g); g.filloval(ball_x, ball_y, 10, 10); // draw a ball of width 10px and // height 10px at [ball_x,ball_y] לאחר הרצת הקוד, הסטודנט גילה שהכדור אכן זז על המסך, אך קיימת בעיית "הבהובים" והכדור לא נע בצורה חלקה: א. מדוע מתרחשת בעיה זו )בתשובתכם ציינו את השורה הרלוונטית(: ב. שנו את הפונקציה (g paint(graphics )בלבד( על מנת לתקן את הבעיה הנ"ל. השתמשו בטכניקה שלמדתם בתרגולים. אין צורך לזכור חתימות מדויקות של פונקציות. במידה ואתם לא זוכרים, אנא כתבו הסבר מדויק על מה הפונקציה עושה. public void paint(graphics g){ 6
שאלה ]8 8 נק'[ עיין בקוד הבא עבור מערכת לסקירת מאמרים אקדמיים. הדרישות מן המערכת הן שסוקר יכול לסקור כל מאמר, בעוד סוקר שהוא סטודנט יכול לסקור רק מאמרים של סטודנטים. public class Paper { public class StudentPaper extends Paper { public class Reviewer { public void review(paper p){ System.out.println("Paper Reviewing "); public class StudentReviewer extends Reviewer { public void review(studentpaper p){ System.out.println("StudentPaper Reviewing "); א. רינה טענה שהמערכת לא אוכפת את הדרישה שסוקר שהוא סטודנט יסקור רק מאמרי סטודנטים. הסבר את טענתה של רינה ב. משה הציע את השינוי הבא בקוד public class Paper { public void review(reviewer r){ System.out.println("Paper Reviewing "); public class StudentPaper extends Paper { public void review(studentreviewer r){ System.out.println("StudentPaper Reviewing "); public class Reviewer { public class StudentReviewer extends Reviewer { 7
האם השינוי שהציע משה אוכף את האילוץ שסוקר שהוא סטודנט יסקור רק מאמרי סטודנטים ג. רינה טענה שעל ידי שינויי הקומפיילר אפשר לאכוף את האילוץ מן המערכת )בהתייחס לקוד של המערכת מסעיף א(. איזה שינוי צריך לבצע בקומפיילר על מנת לפתור את הבעיה? ד. האם השינוי בקומפיילר יכול לגרום לבעיות? אם כן, הסבר את ההשלכות של שינוי זה. אם לא, הסבר מדוע השינוי בטוח. public class Animal { public Animal() { eat(this); public void eat(animal animal) { System.out.println("Animal.eat(Animal)"); שאלה ]12 9 נק'[ עיין בקוד הבא public class Mammal extends Animal { public Mammal() { eat(this); public class TRex extends Mammal { public void eat(animal animal) { System.out.println("TRex.eat(Animal)"); public void eat(mammal mammal) { System.out.println("TRex.eat(Mammal)"); public void eat(trex TRex) { System.out.println("TRex.eat(TRex)"); 8
1. מה יודפס לאחר הרצת הקוד הבא? הסבר את תשובתך Animal animal = new TRex(); 2. רינה הוסיפה למחלקה Mammal את המתודה הבאה: public void eat(mammal mammal) { System.out.println("Mammal.f(Mammal)"); האם תשובתך לסעיף א תשתנה? הסבר מדוע 3. מה יודפס לאחר הרצת הקוד הבא )לפני השינוי בסעיף 2(? הסבר את תשובתך Animal animal = new TRex(); Mammal mammal = new Mammal(); animal.eat(mammal); 4. מה יודפס לאחר הרצת הקוד מסעיף 3 לאחר השינוי בסעיף 2? הסבר את תשובתך 9
שאלה ]8 10 נק'[ class C{ public: C(int r){ x=r; ; void askforhelp(){ cout << "C.foo(): " << x << "!\n"; private: int x; class D: public C { public: void askforhelp(){ cout << "D.foo(): " << y << "!\n"; ; D(int x1, int y1): C(x1){ y=y1; x=x1*x1; private: int y; int x; class E: private D{ public: void askforhelp(){ cout << "E.foo()!\n"; ; E(int x1, int y1, int z1): D(x1,y1){ z=z1; private: int z; ענה על הסעיפים הבאים שמתייחסים להרצת השורות הבאות )1-3(. עבור כל סעיף כתוב את ההדפסה, או הסבר מדוע הקוד אינו עובר קומפילציה. 1. C c(1); 2. D d(2,3); 3. E e(4,5,6); 10
א. c.askforhelp(); ב. c = d; c.askforhelp(); ג. שימו לב הסימן & בהקשר זה מספק את הכתובת של המשתנה // ;d& C c1* = c1->askforhelp(); ד. c=e; c.askforhelp(); שאלה [15 11 נק'] )10 נק') נגדיר מחלקות של מזון המרחיבות את המחלקה האבסטרקטית "אוכל" :)Food( בשר )כולל דגים(.)Meat( מוצרי חלב וביצים.)AnimalProduct( פירות וירקות.)PlantDerived( א. כמו כן נגדיר מס' סוגי אנשים )Person( על פי הרגלי האכילה שלהם: אוכל-כל :)Omnivore) בני אדם שאוכלים כל סוג של אוכל. צמחוני :)Vegetarian( בני אדם שאוכלים הכל חוץ מבשר ודגים )כלומר חוץ מ-.)Meat טבעוניים :)Vegan( בני אדם שאוכלים רק פירות וירקות )כלומר רק.)PlantDerived 11
Food, Meat, AnimalProduct, Plant Derived Person, Omnivore, Vegetarian, Vegan בוב התחיל לבנות תרשים מחלקות עבור המחלקות: המחלקה האבסטרקטית Person מכילה שיטה,isEating אשר מקבלת,Food ומחזירה true אם סוג האדם הקונקרטי אוכל את סוג האוכל שהתקבל כקלט. לדוגמא: Person om = new Omnivore(); Person veget = new vegetarian(); om.iseating(new Meat ()); // return true veget.iseating(new Meat ()); // return false בוב השתמש בתבנית המארח pattern( )Visitor כך שאסור להשתמש ב- instance-of. השלימו את תרשים המחלקות שבוב התחיל לבנות, והוסיפו מימוש לכל מתודה שיצרתם בבלון חיצוני/בתחתית הדף/בין השורות. 12
)5 נק'( אליס הסתכלה על תרשים המחלקות שבוב הכין והבחינה כי יש שימוש חוזר של קוד. היא החליטה לבצע שינויים בתרשים, והגדירה ש: המחלקה Vegan מרחיבה את המחלקה. Vegetarian המחלקה Vegetarian מרחיבה את המחלקה.Omnivore המחלקה Omnivore מרחיבה את המחלקה האבסטרקטית.Person ב. השלימו את תרשים המחלקות שאליס התחילה לשנות כך שאתם שומרים על ההתנהגות של המתודה iseating וחוסכים שכפול קוד ככל הניתן. הוסיפו מימוש לכל מתודה שיצרתם בבלון חיצוני/בתחתית הדף/בין השורות. Visitor<interface> ממשק זה נשאר ללא שינוי מתרשים המחלקות של בוב Omnivore Vegetarian +boolean iseating( ){ Visited חלק זה נשאר ללא שינוי מתרשים המחלקות של בוב Vegan 13
שאלה ]6 12 נק'[ עבור קטעי הקוד הבאים, המחלקה B יורשת מהמחלקה A. לכל קטע קוד, סמנו אם: אין שגיאות, קיימת שגיאת קומפילציה, קיימת שגיאת זמן ריצה 1. Vector<? super B> vec = new Vector<A>(); אין שגיאות / שגיאת קומפילציה / שגיאת זמן ריצה 2. Vector<B> vec = new Vector<? extends A>(); אין שגיאות / שגיאת קומפילציה / שגיאת זמן ריצה 3. Vector<?> vec = new Vector<A>(); vec.add(new B()); אין שגיאות / שגיאת קומפילציה / שגיאת זמן ריצה שאלה ]9 13 נק'[ א. מלאו את השורות החסרות בקטע הקוד הבא על מנת שהקוד יעבור קומפילציה public class Car { public class Mazda { public class Mercedes { public static void printcars(list< > cars) { for (Car c : cars) { System.out.println(c.toString()); public static void main(string[] args) { List< > cars = new ; cars.add(new Mercedes()); cars.add(new Mazda()); printcars(cars); ב. עבור הקוד המעודכן שקיבלת מסעיף א, התווספו השורות הקוד הבאות לפונקצית main List<Mercedes> marcars = new LinkedList<Mercedes>(); marcars.add(new Mercedes()); printcars(marcars); האם הקוד ימשיך להתקמפל? אם התשובה היא לא הצע תיקון 14
ג. עבור הקוד המעודכן שקיבלת מסעיף ב )במידה והיה שינוי(, משה הציע להשתמש בפונקציה הבאה במקום להשתמש בשיטה add של List בצורה מפורשת. public static void addcars(list<? extends Car> cars, Car car) { cars.add(car); כמו כן, משה הוסיף את השורות הבאות לפונקציה main 1. addcars(cars, new Car()); 2. printcars(cars); האם הקוד ימשיך להתקמפל? אם כן מה יודפס על המסך אחרי ביצוע שורה 2 )רק שורה 2(. אם התשובה היא לא, הסבר למה והצע תיקון בהצלחה!!!!! 15