מבחן סיכום לקורס " עקרונות תכנות מונחה עצמים" תאריך הבחינה: 03.07.2018 שמות המרצים: ד"ר עזאם מרעי שם הקורס: עקרונות תכנות מונחה עצמים מספר הקורס: 202-15181 שנה: 2017 סמסטר: ב' מועד: א' משך הבחינה: שלוש שעות חומר עזר: אסור הנחיות כלליות: ההוראות במבחן מנוסחות בלשון זכר, אך מכוונות לנבחנים ולנבחנות כאחד. נא לוודא כי בשאלון זה 13 עמודים. יש לענות על כל השאלות בגוף המבחן בלבד. אין לחרוג מהמקום המוקצה )במקרים חריגים יש לבקש אישור ממרצה\מתרגל(. מומלץ להשתמש במחברת הבחינה כטיוטא. בשאלות רב-ברירה )"אמריקאיות"( יש לסמן תשובה אחת, אלא אם צוין אחרת בגוף השאלה. בשאלות רב-ברירה בהן לא נידרש לנמק, ניתן לסמן תשובה ללא נימוק, אך ניתן גם לספק נימוק קצר, אם רצונכם בכך )חובה לתת נימוק רק בשאלות בהן זה מצוין מפורשות בשאלה(. במידה ואין ניקוד על הסעיפים, כל סעיף מקבל מספר שווה של נקודות )הניקוד לכל השאלה מחולק למספר הסעיפים(. הקוד כתוב בשפת,Java פרט לשאלות בהן מצוין אחרת. אם אינך יודע את התשובה, ניתן לכתוב "לא יודע" ולקבל 20% מהניקוד על הסעיף\השאלה. )1 )2 )3 )4 )5 )6 )7 )8
שאלה ]5 1 נק'[ סמן סוג היחס התקין בין זוגי המחלקות הבאים 1. is-a 1. is-a 1. is-a 1. is-a 1. is-a זוג מחלקות מרצה, מרצה בכיר מחסנית, ויקטור מחלקה, עובדים רכבת, קרון מחשב, מעבד יחס 2. has-a 2. has-a 2. has-a 2. has-a 2. has-a שאלה ]9 2 נק'[ מחלקה מספקת כמה יכולות חשובות. ציינו שלושה כאלה והסבירו אותם.1.2.3 שאלה ]9 3 נק'[ עבור כל טענה סמנו אם היא נכונה או לא נכונה לא נכון \ בשפת ג'אווה - היררכיית ירושה תמיד ניתנת לייצוג באמצעות עץ. נכון א. לא נכון \ בשפת ++C - היררכיית ירושה תמיד ניתנת לייצוג באמצעות יער. נכון ב. מנגנון ה interface ב Java מיותר. השימוש במחלקות אבסטרקטיות יכול להחליף לחלוטין את השימוש במנשקים ג. לא נכון \ נכון לא נכון \ כל השפות הסטטיות מחייבות הצמדת טיפוס לכל משתנה נכון ד. בשפות דינאמיות, משתנים הם רק שמות, טיפוסים נקשרים לערכים שמחזיקים המשתנים בזמן ריצה, אך ברגע ה. לא נכון \ שמשתנה נקשר לערך עם טיפוס מסוים, אין אפשרות להציב לו ערך עם טיפוס אחר. נכון בשפות סטטיות לא מונחות עצמים החוקיות של שיטה מוכרעת בזמן קומפילציה, בעוד בשפות סטטיות מונחות עצמים ו. לא נכון \ החוקיות של שיטה יכולה להיקבע גם בזמן ריצה על סמך המחלקה הדינמית. נכון לא נכון \ צימוד Coupling( מ( ייצג את חוזק הקשר בין פעולות שונות תחת אותו רכיב. נכון ז. לא נכון \ מנגנון ה overloading -קובע איזו שיטה תקרא בזמן קומפילציה ע"פ הטיפוס הסטטי של הפרמטרים. נכון ח. לא נכון \ מנגנון ה overriding -קובע איזו שיטה תקרא בזמן ריצה ע"פ הטיפוס הסטטי של הפרמטרים. נכון ט. 2
שאלה ]5 4 נק'[ ציינו שני טיעונים, לטובת השימוש בשפות סטטיות.1.2 public class StarfleetOfficer { צי- הכוכבים //Starfleet: protected String name; public StarfleetOfficer(String name) { this.name = name; שאלה ]12 5 נק'[ לפניך קטע קוד הכתוב בשפת :Java public class Captain extends StarfleetOfficer { public Captain(String name) { super(name); public class Spaceship { protected StarfleetOfficer incharge; public StarfleetOfficer getincharge() { return incharge; public void setincharge(starfleetofficer incharge) { this.incharge = incharge; public class Enterprise extends Spaceship { public Captain getincharge() { return (Captain) incharge; public void setincharge(captain captain) { this.incharge=captain; 3
א. האם אפשרי שמפקד כלשהו בצי הכוכבים Srarfleet יהיה אחראי על ספינת החלל Enterprise אם כן הסבר איזה מנגנון מאפשר את זה והדגים את תשובתך בקוד (Java). אחרת הסבר למה.? ב. מרחיבים את הקוד של המחלקה Enterprise שתכלול את השדה.protected Captain incharge האם אפשר להריץ את הקוד למטה ללא שגיאות? אם התשובה חיובית כתבו מה יודפס אחרת ציינו ונמקו את סוג השגיאה )שגיאת קומפילציה או שגיאת זמן ריצה( Spaceship enterprised = new Enterprise(); StarfleetOfficer captin = new Captain("Jean-Luc Picard"); enterprised.setincharge(captin); System.out.println(enterpriseD.getInCharge().name); ג. המתודה הבאה מקבלת מערך של ספינות-חלל ומערך של מפקדים כלליים את מערך הספינות, וכל ספינה מקבלת מפקד שמתאים לה. של צי-הכוכבים. השיטה משכנת public static void chargewith(spaceship[] spaceships, StarfleetOfficer[] starfleetofficers){ for(int i=0; i<starfleetofficers.length;i++) { if(starfleetofficers[i] instanceof Captain){ spaceships[i]=new Enterprise(); else if(starfleetofficers[i] instanceof StarfleetOfficer){ spaceships[i]=new Spaceship(); spaceships[i].setincharge(starfleetofficers[i]); 4
בהנחה שבמערך starfleetofficers אין ערכי null והאורך שלו כאורך,spaceships האם השימוש בשיטה זו בטוח, כלומר לא מוביל לשגיאות ריצה. אם התשובה שלכם היא לא, הדגימו בקוד קצר תרחיש שבו תהיה שגיאת ריצה. אחרת הסבירו למה. class A { public: virtual void f () { cout << "I am In A"; ; class B:public A {; class C:public A{; class D:public B, public C{; שאלה ]5 5 נק'[ נתון הקוד הבא בשפת ++C: א. עבור שורות ההרצה הבאות D *d1 = new D (); d1->f(); error: request for member 'f' is ambiguous מתקבלת שגיאת הקומפילציה הבאה הסבירו את מקור שגיאת הקומפילציה 5
ב. הוספה של הצהרה אחת )מילה שמורה( בשני מקומות פותרת את הבעיה. ציינו הצהרה זו ואיפה צריך לכתוב אותה שאלה ]7 6 נק'[ לפניכם קוד הכתוב בשפת ++C המדמה הושבה של נוסעים במטוס. במטוס ישנן שתי מחלקות: מחלקה רגילה ומחלקת עסקים. לכל מושב במטוס יש את השורה והעמודה בה הוא נמצא. המחלקה Passenger מייצגת נוסע בטיסה. המחלקה AirplaneSeat מייצגת מושב במחלקה הרגילה. המחלקה BusinessClassSeat מייצגת מושב במחלקת העסקים. מחלקת עסקים מחלקה רגילה ניתן לראות שבמחלקה הרגילה, הנוסעים יושבים בעמודות A-C, H-K ובשורות 21 והלאה, ובמחלקת עסקים הנוסעים יושבים בעמודות A,C,H,K ובשורות.10-13 class Passenger { public: string _name; int _age; ; Passenger(string name, int age) : _name(name), _age(age) { class AirplaneSeat { public: char _column; int _row; Passenger* _passanger; ; AirplaneSeat(char column, int row, Passenger* passenger) : _column(column), _row(row), _passanger(passenger) { class BusinessClassSeat : public AirplaneSeat { public: bool _has_table; ; BusinessClassSeat(char col, int row, Passenger* pas, bool table) : AirplaneSeat(col, row, pas) { this->_has_table = table; 6
עליכם לסרטט את תמונה הזיכרון לאחר ביצוע כל שורות הקוד הבאות. יש לסרטט את תמונת הזיכרון עבור ה Stack ועבור ה Heap )בעמוד הבא(. void main() { Passenger *azzam = new Passenger("Azzam", 35); Passenger *matan = new Passenger("Matan", 28); Passenger *yodan = new Passenger("Yodan", 32); AirplaneSeat *as1 = new AirplaneSeat('A', 22, azzam); char col1 = 'H'; AirplaneSeat *bcs1 = new BusinessClassSeat(col1, 10, matan, true); int* row1 = new int(12); BusinessClassSeat bcs2(col1, *row1, yodan, false); AirplaneSeat as2 = bcs2; Stack Heap שאלה ]6 7 נק'[ class A { public: virtual void f(){cout << "I am in A";; ; class B : public A { private: virtual void f(){cout << "I am in B";;; הקוד הבא ב ++C, עובר קומפילציה 7
A *p = new B(); p->f(); אחרי הרצה של השורות הבאות התקבלה התשובה )עובר זמן ריצה( I am in B א. איזה תכונה הופרה בו 8 ב. האם הפרה זו תמשיך להתקיים גם אם הופכים את השיטות להיות לא וירטואליות? אם כן תנו דוגמה,אחרת הסבירו מדוע לא. ג. האם הבעיה מסעיף א' קיימת גם בשפת Java?נמקו. שאלה ]6 8 נק'[ עיינו בקוד הבא. הקוד של שתי המחלקות הוא רק חלקי ומכיל עוד שיטות ושדות public class Employee { private String name; private String email; public String getname() { return name; public String getemail() { return email;.//rest of code public class Emailer { public void sendemail(employee employee, String text){ String name = employee.getname(); String email = employee.getemail();.// rest of code.// rest of code
א. האם קוד זה מציג בעיה של צימוד (Coupling) או מציג לכידות (Cohesion)? הסבירו את תשובתכם ב. במידה ויש בעיה של צימוד, הציעו תיקון שיפתור בעיה זו, במידה ואין כתבו אין בעיה שאלה ]5 9 נק'[ בתרגול ראינו פתרון פרוצדוראלי לבעיית N המלכות ופתרון מונחה עצמים לאותה הבעיה. הפתרון השני, מונחה העצמים היה יעיל )במונחי זמן ריצה( בהרבה, מדוע? א. תכנות מונחה עצמים שינה את החשיבה שלנו ולכן הפתרון השני היה יעיל יותר, תכנות מונחה עצמים עצמו לא בהכרח יעיל יותר מתכנות פרוצדוראלי. ב. תכנות מונחה עצמים תמיד יעיל יותר מתכנות פרוצדוראלי ולכן הפתרון השני היה יעיל יותר. ג. בחלק מהמקרים תכנות מונחה עצמים יעיל יותר מתכנות פרוצדוראלי ולכן הפתרון השני היה יעיל יותר במקרה הזה. ד. תכנות מונחה עצמים מאפשר לנו לעשות דברים שלא ניתן לעשות בעזרת תכנות פרוצדוראלי ולכן אפשר לנו לפתור את הבעיה בשיטה שונה, יעילה יותר שלא יכולנו לממש בתכנות פרוצדוראלי. שאלה ]6 10 נק'[ א. ב. מה הם ההבדלים בין GridLayout לבין?GridBagLayout בשימוש ב- GridLayout יש יותר חופש למקם איברים בתאים צמודים. a. GridLayout הינו רשת בעוד השני הוא לא b. ל- GridBagLayout יש אובייקט אילוצים ולכן המשתמש יכול לשלוט באופן התנהגות האיברים בתאים. c. Listener והשני Event אחד.d השיטה (g paint(graphics נקראת כאשר )סמן את כל התשובות הנכונות(: הרכיב נוצר. a. העכבר עובר על הרכיב. b. העכבר לוחץ על הרכיב. c. הרכיב משנה גודל. d. נקראת השיטה repaint() של הרכיב. e. הרכיב הופך לבלתי נראה. f. הרכיב הופך לנראה. g. שינוי בשדה בתוך הרכיב. h. 9
שאלה ]13 11 נק'[ הנהלת האוניברסיטה החליטה לבנות מערכת לצפייה בקורסים מכוונים. צפייה בקורס מחייבת כמובן רישום לקורס, ותשלום. כמו כן המערכת תומכת בבדיקות שונות טרם הרישום או הצפייה. להלן המדיניות שנתמכות במערכות: 1. מדיניות תשלום אשר מחייב תשלום עבור כל קורס )PAYMENT( 2. מדיניות רישום לקורסים אשר מנתק אותך אם לא נגעת בו במשך דקה ולא נותן לך להתחבר במשך 3 דקות. אם ניסית להתחבר בחלון הזמן הנתון, המנגנון מאפס את 3 הדקות ומתחיל לספור מחדש. )REGISTER( 3. מדיניות צפייה בקורס -Streaming הזרמה של התוכן הנבחר. צפייה בעוד תוכן תתאפשר רק אחרי שעתיים. בכל מדניות,)Policy( המימוש הבסיסי הוא כמתואר, אך עבור כל סוג סטודנט )תואר ראשון, שני, שלישי או אורח(, המימוש יכול להיות קצת שונה )למשל אורח יכול לצפות רק בתוכן אחד ביום(. למחלקת מדיניות )Policy( יש שיטה )לא בהכרח אבסטרקטית( st) applypolicy(student המקבלת סטודנט ומפעילה שירות. ]10 נק'[ בנה תרשים מחלקות עבור הבעיה למעלה, ובו לפחות המחלקות הבאות: Policy, Student ושבע המחלקות היורשות מהן. ליד כל שיטה הראה את מימושה בקצרה בבלון חיצוני. הימנעו משימוש ב.Visitor Pattern והשתמשו ב instanceof א. 10
ב. ]1 נק'[ הסבר מדוע בחרת לייצג כל מחלקה כ Visitor או.Visited ]2 נק'[ לפניכם שתי דרישות שנשיאת האוניברסיטה יכולה להחליט לבצע, הסבירו מה נדרש לשנות במימוש על מנת להוסיף כל אחת מהדרישות: 1. הוספת תמיכה בסטודנטים הלומדים במסגרת קורס טיס. 2. הוספת מנגנון ספאם אשר שולח כל מייל מהאוניברסיטה 5 פעמים. ג. שאלה ]12 12 נק'[ נתונות ההגדרות הבאות )לכל מחלקה קיים בנאי ברירת מחדל(: class Animal{/*... */ class Cat extends Animal{/*... */ לכל שורות הקוד הבאות, הקיפו בעיגול האם השורות תקינות, יוצרות שגיאת קומפילציה או שגיאה בזמן ריצה: Collection<? super Cat> v1 = new Vector<Animal>(); א. ]0.5 נק'[ 3. השורות תקינות. Vector<? super Cat> v2 = new Vector<Animal>(); ב. ]0.5 נק'[ 3. השורות תקינות. Vector<? extends Animal> v3 = new Vector<Cat>(); Cat c = v3.get(0); ג. ]1 נק'[ 3. השורות תקינות. 11
Vector<? super Animal> v4 = new Vector<Cat>(); Animal a = v4.get(0); ד. ]1 נק'[ 3. השורות תקינות. Vector<? extends Cat> v5 = new Vector<Cat>(); v5.add(new Cat()); ה. ]1 נק'[ 3. השורות תקינות. עבור השאלות הבאות נתונות השיטות הבאות: static void foo(object a){ System.out.println("Object"); static void foo(animal a){ System.out.println("Animal"); static void foo(cat a){ System.out.println("Cat"); בנוסף נתונים הווקטורים הבאים )הקוד הנ"ל עובר קומפילציה ורץ ללא שגיאות(: Vector<Animal> va = new Vector<Animal>(); Vector<Cat> vc = new Vector<Cat>(); va.add(new Cat()); vc.add(new Cat()); לכל שורות הקוד הבאות, הקיפו בעיגול האם השורות יוצרות שגיאת קומפילציה, שגיאה בזמן ריצה או שהשורות תקינות, אם השורות תקינות כתבו מה יודפס: Vector<? super Animal> v6 = va; foo(v6.get(0)); ו. ]2 נק'[ 3. השורות תקינות ויודפס: Vector<? super Cat> v7 = va; foo(v7.get(0)); ז. ]2 נק'[ 3. השורות תקינות ויודפס: 12
Vector<? extends Cat> v8 = va; foo(v8.get(0)); ח. ]2 נק'[ 3. השורות תקינות ויודפס: Vector<? extends Animal> v9 = vc; foo(v9.get(0)); ט. ]2 נק'[ 3. השורות תקינות ויודפס: בהצלחה!!!!! 13