310 likes | 453 Views
הגדרת משתנה עצם דומה, אך לא זהה, להגדרת משתנה פשוט. להבדל יש משמעויות חשובות. כדי להבין אותו נחזור לטבלת המשתנים. נשווה בין הטיפוס הפשוט int לטיפוס העצם מהמחלקה Dog. לשם כך נוסיף למחלקה Dog בונה חדש:. public Dog(String name) { this(name,HAPPY); }. ושיטות חדשות:.
E N D
הגדרת משתנה עצם דומה, אך לא זהה, להגדרת משתנה פשוט. להבדל יש משמעויות חשובות. כדי להבין אותו נחזור לטבלת המשתנים. נשווה בין הטיפוס הפשוט int לטיפוס העצם מהמחלקה Dog
לשם כך נוסיף למחלקה Dog בונה חדש: public Dog(String name) { this(name,HAPPY); } ושיטות חדשות: public String get_name() { return name; } public void set_name(String name) { this.name = name; }
אחרי בצוע הפקודה int i; יראו הזיכרון וטבלת המשתנים כך: טבלת משתנים זיכרון
2. אחרי בצוע הפקודה i = 1; יראו הזיכרון וטבלת המשתנים כך: טבלת משתנים זיכרון 1
3. אחרי בצוע הפקודה int j; יראו הזיכרון וטבלת המשתנים כך: טבלת משתנים זיכרון 1
4. אחרי בצוע הפקודה j = iיראו הזיכרון וטבלת המשתנים כך: טבלת משתנים זיכרון 1 1 הערך שהיה במקום עליו מצביע i הועתק למקום עליו מצביע j.
5. אחרי בצוע הפקודה j = 2;יראו הזיכרון וטבלת המשתנים כך: טבלת משתנים זיכרון 1 2 System.out.println(“i = “+i+” “+ ”j = “+j); יצור פלט: i = 1 j = 2
6. לעומת זאת, אחרי בצוע הפקודה Dog my_dog; יראו הזיכרון וטבלת המשתנים כך: טבלת משתנים זיכרון 1 2 שום מקום לא הוקצה בזיכרון
7. זיכרון יוקצה רק בבצוע הפקודה my_dog = new Dog(“Rex”); . טבלת משתנים זיכרון 1 2 Rex
8. Dog your_dog; טבלת משתנים זיכרון 1 2 Rex
8. פעולת ההצבה your_dog = my_dog; עושה משהו אחר לגמרי מאשר j = i; . טבלת משתנים זיכרון 1 2 Rex לא הוקצה זיכרון נוסף ולא הועתקו ערכים
9. נשנה את הערך של your_dog על ידי your_dog.set_name(“Hetz”); טבלת משתנים זיכרון 1 2 Hetz לא הוקצה זיכרון נוסף ולא הועתקו ערכים my_dog השתנה!!!
לסכום ערכי משתנים פשוטים מוצבים ע"י ערך. ערכי עצמים מוצבים בהפניה. ומה באשר להצבת משתנים כפרמטרים לפונקציות? אותו דבר
1. כזכור, אחרי בצוע הפקודות i = 7; ו j = i נראו הזיכרון וטבלת המשתנים כך: טבלת משתנים זיכרון 7 7 public static int change_me(int m) { m = m – 5; return m ; } נגדיר פונקציה חדשה
2. ניקרא לפונקציה על ידי j = change_me(i) . טבלת משתנים טבלת משתנים זיכרון 7 7 הקריאה לפונקציה יוצרת טבלת משתנים חדשה, המכסה את הקודמת. מוקצה מקום בזיכרון עבור המשתנה הפורמאלי m.
3. הערך של המשתנה האקטואלי (i) מועתק למשתנה הפורמאלי .(m) טבלת משתנים טבלת משתנים זיכרון 7 7 7 4. גוף הפונקציה מתבצע טבלת משתנים טבלת משתנים זיכרון 7 7 2
5. בחזרה מהפונקציה : א. j מקבל את ערך ההחזרה. ב. הזיכרון שהוקצה לפונקציה מתנקה. ג. טבלת המשתנים של הפונקציה מוסרת. טבלת משתנים זיכרון 2 7
public class Dog_driver4 { public static void main(String[] args) { Dog canis = new Dog(“Rex”); Dog canis1; canis1 = change_name(canis,”Tushtush”); canis.voice(); canis1.voice(); System.out.println(canis == canis1); } public static Dog change_name(Dog 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
אחרי Dog canis = new Dog(“Rex”); Dog canis1; טבלת משתנים זיכרון Rex
בזמן בצוע הפונקציה טבלת משתנים טבלת משתנים זיכרון Tushtush בחזרה מהפונקציה טבלת משתנים זיכרון Tushtush
נגדיר עתה מחלקה Pack שתייצג להקת כלבים. לפני שנכתוב אותה נראה איך צריך לשנות את המחלקה Dog. א. נוסיף משתנה עצם פרטי my_pack ונאתחל אותו להיות null , כלומר ברירת המחדל היא שהכלב אינו חבר בלהקה. ;private Pack my_pack = null ב. נוסיף שיטות: public Pack get_pack() { return my_pack; } public boolean set_pack(Pack pack) { if (my_pack != null) return false; my_pack = pack; return true; }
public class Pack { static public final int MAX_MEMBERS = 10; private Dog[] members; private int number_of_members; private String name; public Pack(String name) { this.name = name; members = new Dog[MAX_MEMBERS]; number_of_members = 0; } public int size() { return number_of_members; } public String toString() { return "a Pack called "+name; } }
public boolean add_member(Dog candidate) { if (number_of_members >= MAX_MEMBERS) { System.out.println("Pack is full “+ “cannot add "+ candidate); return false; } for (int idog = 0; idog < size();idog++) if (members[idog] == candidate) { System.out.println(candidate + ” already_in”); return false; } members[number_of_members] = candidate; candidate.set_pack(this); number_of_members++; return true; } }
Public class Dog_driver5 { static void main(String[] args) { Pack pack1 = new Pack(“mountain”); Pack pack2 = new Pack(“field”); Dog canis = new Dog(“Rex”); Dog canis1 = new Dog(“Tushtush”); pack1.add_member(canis); canis1.set_pack(pack2); System.out.println(canis+” belongs_to “+canis.get_pack()+ “of size “+ canis.get_pack().size()); System.out.println(canis1+” belongs_to “+canis1.get_pack()+ “of size “+ canis1.get_pack().size()); } }
פלט The dog called Rex belongs_to a Pack called mountain of size 1 The dog called Tushtush belongs_to a Pack called field of size 0
נשנה את שיטה set_pack של Dog. public boolean set_pack(Pack pack) { if (my_pack != null) return false; my_pack = pack; pack.add_member(this) ; return true; }
אכן צריך לשנות אותה עוד public boolean set_pack(Pack pack) { if (my_pack != null) return false; if (!pack.has_place()) if (pack.is_included(this)) { my_pack = pack; return true; } else return false; my_pack = pack; pack.add_member(this); return true; }
כאשר השיטות החדשות במחלקה Pack הן: public boolean is_included(Dog dog) { for (int idog = 0; idog < size();idog++) if (members[idog] == dog) { return true; } return false; } public boolean has_place() { return (size() < MAX_MEMBERS); }
ו add_member שונה ל public boolean add_member(Dog candidate) { if (number_of_members >= MAX_MEMBERS) { System.out.println("Pack is full "); return false; } if (is_included(candidate)) return false; if ((candidate.get_pack() == null)|| (candidate.get_pack() == this)) { members[number_of_members] = candidate; number_of_members++; candidate.set_pack(this); return true; } return false; }
פלט The dog called Rex belongs_to a Pack called mountain of size 1 The dog called Tushtush belongs_to a Pack called field of size 1