300 likes | 473 Views
הערות על הבוחן 1. הבוחן כולל את כל החומר שנלמד בקורס עד ( כולל ) מבוא לעצמים. הורשה אינה נכללת בחומר לבוחן 2. הבוחן כולל את החומר שנלמד בתרגילים את הפרקים א-ז בספר "פרקי מבוא במדעי המחשב" ואת כל החומר הרלבנטי באתרים של המורים השונים.
E N D
הערות על הבוחן 1. הבוחן כולל את כל החומר שנלמד בקורס עד (כולל) מבוא לעצמים. הורשה אינה נכללת בחומר לבוחן 2. הבוחן כולל את החומר שנלמד בתרגילים את הפרקים א-ז בספר "פרקי מבוא במדעי המחשב" ואת כל החומר הרלבנטי באתרים של המורים השונים. 3. מומלץ לעיין בבוחן של שנה שעברה. מתכונת הבוחן השנה תהיה דומה. כל נבחן יקבל: א. חוברת שאלות שאליה מצורף דף תשובות אחד. ב. חוברת בחינה שתשמש לטיוטה בלבד. בסוף הבוחן יאספו רק דפי התשובות. תשובות במחברת הטיוטה לא יקראו. 4. המקום בדף התשובות הוקצה בנדיבות. אם תשובתכם ארוכה מכדי להיכנס במקום שהוקצה לה, היא כנראה לא נכונה. 3. בזמן הבוחן המורים לא יענו על שאלות כדי שלא להעניק יתרון בלתי הוגן לחלק קטן מהסטודנטים. סטודנטים החוששים שיפגעו בגלל אי ידיעת עברית מתבקשים לגשת אל אחד המרצים לפני הבוחן.
לאור הצלחתנו לדמות כלב. קיבלנו משימה חדשה לדמות רובוט של כלב באמצעות המחלקה RobDog הרובוט דומה להפליא לכלב להוציא מספר הבדלים דקים: א. במקום בשר הרובוט אוכל סוללות. ב. במקום לנבוח הוא שורק tootoo. ג. הוא יודע קצת חשבון. במבט ראשון נראה שעלינו לחזור על כל התהליך מההתחלה עניין מיגע למדי.
הדרך הקלה (ולכן הנכונה) לעשות זאת היא באמצעות מנגנון ההורשה (inheritance). המחלקה RobDogתירש את המחלקה Dog.
ההגדרה public class RobDog extends Dog { } בקובץ RobDog.java יוצרת מחלקה חדשה. המשתנים והשיטות הפומביות שלה זהים לאלו של .Dog אנו אומרים שהמחלקה RobDog ירשה אותם מהמחלקה Dog. עוד נורש באופן אוטומטי הבונה הריק.
public class RobDog_driver1 { public static void main(String[] args) { RobDog canis = new RobDog(); RobDog canis1; canis1 = change_name(canis,"Tushtush"); canis.voice(); canis1.voice(); System.out.println(canis == canis1); } public static RobDog change_name(RobDog to_change, String new_name) { to_change.set_name(new_name); return to_change; } }
פלט The dog called Tushtush: HAAU The dog called Tushtush: HAAU true
עם זאת, חשוב לזכור שהמחלקה היורשת נמצאת מחוץ לכמוסה של המחלקה המורישה. אי אפשר להגדיר ב RobDog שיטה חדשה public void set_name_to_peng() { name = “peng”; }
כדי לשנות את המשתנה הפרטי של Dogname - חייבים לעבור דרך השיטההציבורית set_name. public void set_name_to_peng() { set_name(“peng”); }
אנחנו כמובן לא מסתפקים בבונה אחד public RobDog(String name, int mood) { super(name,mood); } public RobDog(String name){ super(name); } public RobDog(){ super(); } ולמען השלמות
public RobDog(String name, int mood) { super(name,mood); } public RobDog(String name){ super(name); } public RobDog(){ super(); } שימו לב לשמוש ב super(…) המאפשר לנו לפנות אל בונה של מחלקת האם Dog. שימו גם לב שבדומה ל this(…) super(…) חיב להופיע בשורה ה ראשונה.
בשלב זה המחלקהRobDog כמעט זהה למחלקה Dog. נתחיל לשנות אותה כך, שהעצמים יהיו רובוטים כלביים ולא כלבים ממש.
שלב א. שינוי הקולות נגדיר בRobDog קבוע מחרוזת חדש עבור השריקות של הרובוט. ונשנה את השיטה voice כך שתשרוק במקום לנבוח. לשינוי כזה בשיטה של מחלקה יורשת קוראים דריסה (overriding). public static final String WHISTLE = “TOOTOO”;
לכאורה מספיק להעתיק את השיטה voice(int) מ המחלקה Dog למחלקה RobDog ולשנות מלה אחת
public void voice(int n_sounds) { String sound; int sound_counter; if (n_sounds <= 0 ) { System.out.println("Error in Dog.voice: "+ "Cannot produce zero or fewer sounds"); return; } if (mood == HAPPY) sound = WHISTLE; else if (mood == SAD) sound = HOWL; else sound = "Unknown mood "+mood; System.out.print(this+": "); for (sound_counter = 0; sound_counter< n_sounds; sound_counter++) System.out.print(sound+" "); System.out.println(); } אולם אז נכפיל את מספר שורות הקוד (ואת הסיכויים לטעות).
מוטב במחלקה Dog להעמיס שיטה נוספת כללית יותר על voice . public void voice(int n_sounds, Stringhappy_sound,String sad_sound)
public void voice(int n_sounds,Stringhappy_sound,String sad_sound) { String sound; int sound_counter; if (n_sounds <= 0 ) { System.out.println("Error in Dog.voice: "+ "Cannot produce zero or fewer sounds"); return; } if (mood == HAPPY) sound =happy_sound; else if (mood == SAD) sound = sad_sound; else sound = "Unknown mood "+mood; System.out.print(this+": "); for (sound_counter = 0; sound_counter< n_sounds; sound_counter++) System.out.print(sound+" "); System.out.println(); }
עכשיו נכתוב מחדש את voice (int) במחלקה Dog public void voice(int n_sounds) { voice(n_sounds,BARK,HOWL); } ונכתוב בקלות את השיטה הדורסת במחלקה RobDog. public void voice(int n_sounds) { voice(n_sounds,WHISTLE,HOWL); } שימו לב אין צורך לכתוב מחדש את השיטה voice() במחלקה Dog ואין צורך לדרוס אותה
הבקיאות של הרובוט שלנו בחשבון מתבטאת בהעמסה נוספת של voice שקימת רק ב RobDog public void voice(int n, int m) { voice(n*m); }
שלב ב. נדרוס את toString() . public String toString() { return "The robot dog called "+get_name(); }
שלב ג. נשנה את סוג המזון החביב על הרובוטים. לשם כך צריך להגדיר ב Dog שיטה חדשה public void set_eats(String food) { eats = food; }
ונשנה מעט את הבונים של RobDog : public RobDog(String name, int mood) { super(name,mood); set_eats(“battery ”); } public RobDog(String name){ super(name); set_eats(“battery ”); } public RobDog(){ super(); set_eats(“battery ”); }
שימוש נוסף ב super - הרובוט רוצה להתחזות לדבר האמיתי נגדיר במחלקה RobDog public void pretend_to_be_a_dog(int n) { super.voice(n); }
Public class RobDog_driver { public static void main(String[] args) { RobDog rob = new RobDog(); rob.voice(2,2); rob.eat(“meat”); rob.voice(2,3); rob.eat(“battery”); rob.voice(2,4); rob.pretend_to_be_a_dog(3); } }
פלט The robot dog called dog_number0: TOOTOO TOOTOO TOOTOO TOOTOO The robot dog called dog_number0: OOOOOO OOOOOO OOOOOO OOOOOO OOOOOO OOOOOO The robot dog called dog_number0: TOOTOO TOOTOO TOOTOO TOOTOO TOOTOO TOOTOO TOOTOO TOOTOO The robot dog called dog_number0: HAAU HAAU HAAU The robot dog called dog_number0: TOOTOO TOOTOO TOOTOO TOOTOO The robot dog called dog_number0: OOOOOO OOOOOO OOOOOO OOOOOO OOOOOO OOOOOO The robot dog called dog_number0: TOOTOO TOOTOO TOOTOO TOOTOO TOOTOO TOOTOO TOOTOO TOOTOO The robot dog called dog_number0: HAAU HAAU HAAU
כעת מבקשים מאתנו חתול מבחינות רבות חתול דומה לכלב ולא נרצה לכתוב את המחלקה Cat מההתחלה. מצד שני המחלקה Cat לא יכולה לרשת את המחלקה Dog. למשל, אין הגיון שבתפריט של Cat תהיה שיטה set_pack . (חתולים לעולם אינם מתארגנים בלהקות)
המהלך הנדרש מאתנו הוא הפשטה (abstraction) עלינו לזהות את המהות המופשטת, שמאחורי שני הטיפוסים המוחשיים: כלב ו חתול - שניהם יונקים. המחלקה Mammal תכיל לכן חלק ניכר מהקוד שהופיע קודם ב מחלקה Dog. המחלקה Dog תהפוך להיות Public class Dog extends Mammal והמחלקה Cat תיכתב כ Public class Cat extends Mammal
ככל שנמשיך בפרויקט ילך ויבנה עץ ההורשה Organism Archeon Microbe Plant Animal Insect Bird Fish Mammal Reptile Chicken Cat Dog RobDog
ב Java (כמעט) כל המחלקות יורשות. אם אין למחלקה מחלקת אם מפורשת – מחלקת האם שלה היא Object