תכנות מתקדם ב-Java/עבודה לפי ממשק: הבדלים בין גרסאות בדף

תוכן שנמחק תוכן שנוסף
Johnny Zoo (שיחה | תרומות)
מאין תקציר עריכה
Johnny Zoo (שיחה | תרומות)
שורה 31:
====יתרונות====
# אם יש צורך שכל שינוי במשתנה יגרור שינויים נוספים - ניתן לבצע זאת בעזרת שיטת ה-set.
# החזרה בעזרת שיטת get מאפשרת לנו למנוע מהמשתמש (כלומר, מי שניגש לקבל את האובייקט) לשנות את המשתנה שאנו מחזירים. כאשר מחזירים משתנים פרימיטיביים, חוזר עותק של המשתנה ולא המקור (החזרה של ערך המשתנה ולא של המשתנה עצמו - By value). לכן, לא ניתן לשנות ערכים אלה של המחלקה בעזרת שינוי התוצאה המתקבלת בעזרת get. כאשר מדובר באובייקטים או מערכים אפשר לדאוג לכך שנחזיר רק עותק של האובייקט - ראו בהמשך.
 
{{הארה|בחלק מסביבות העבודה ניתן ליצור את שיטות ה-get וה-set באופן אוטומטי.}}
 
====החזרה של מערכים ואובייקטים====
בג'אווה, כאשר שיטה מחזירה אובייקטים או מערכים - חוזרת הפניה ולא עותק של האובייקט. לכן, מי שמקבל את אותה ההפניה יכול להשתמש בה כדי לשנות את האובייקט או את המערך - אפשרות שאינה תמיד רצויה מבחינתנו. לכן, במצבים כאלה נדאג ששיטת ה-get תחזיר '''עותק חדש''' של האובייקט שנרצה להחזיר. לשם הדוגמה, נניח שיש לנו מחלקה בשם ClosedObject שאחד השדות שלה הוא אובייקט מטיפוס בשם Blackbox - אובייקט שאנו לא רוצים לאפשר למחלקות אחרות לשנות. הקוד של המחלקה Blackbox יראה, למשל, כך:
<source lang = "java">
public class Blackbox {
 
private int _someField;
public int getField() {
return _someField;
}
public void setField(int val) {
_someField = val;
}
}
</source>
המחלקה CloseObject תיראה כך:
<source lang = "java">
public class ClosedObject {
private Blackbox _box;
public ClosedObject() {
_box = new Blackbox();
_box.setField(10);
}
public Blackbox getBox() {
return _box;
}
public void printBox() {
System.out.println("What is in the box? "+_box.getField());
}
}
</source>
כעת, נניח שמחלקה אחרת כלשהי משתמשת באובייקט מסוג ClosedObject, באופן הבא:
<source lang = "java">
ClosedObject obj = new ClosedObject();
obj.printBox();
Blackbox myBlackBox = obj.getBox();
myBlackBox.setField(11);
obj.printBox();
</source>
נסו להריץ את הקוד. מה יקרה? כאשר אנו משנים את האובייקט שקיבלנו בעזרת המחלקה get משתנה גם האובייקט המקורי - תוצאה לא רצוייה. כדי לתקן את הבעייה הזאת, נשנה את פונקציית ההחזרה שלנו כך שיוחזר רק עותק. למשל:
<source lang = "java">
public Blackbox getBox() {
Blackbox temp = new Blackbox();
temp.setField(_box.getField());
return temp;
}
</source>
הפעולות שיתבצעו כעת על האובייקט המוחזר לא ישפיעו על האובייקט הפרטי שנמצא באותה מחלקה. בשיטה זו יש בעייתיות מסויימת: אם אנחנו מחזירים אובייקט גדול - פעולת ההעתקה עשוייה לצרוך זמן רב, ולבזבז כמות זיכרון גדולה שתידרש ליצירת ההעתק. לכן, הפרידו בין מקרים בהם תעדיפו להחזיר עותק של האובייקט, לבין מקרים בהם תעדיפו להחזיר מצביע לאובייקט (כלומר - החזרה פשוטה, כפי שראינו עד עכשיו).
 
==עבודה על פי ממשק==