שאלה על תכונות עצמים - תכנות - HWzone פורומים
עבור לתוכן
  • צור חשבון

שאלה על תכונות עצמים


davidcohen

Recommended Posts

היי

יש לי שאלה בנוגע לתכונות של אובייקטים.

לאחר שהגדרתי תכונה של עצם מסויים כ private אני עושה שיטה כדי שמחלקות אחרות יוכלו לקבל את הנתון.

לדוגמא, יש לי מחלקה שיוצרת רשומה שכוללת פרטים על אנשים (שם פרטי, שם משפחה, ומספר טלפון) נגיד שאני רוצה לכתו שיטה שמחזירה את השם הפרטי על מנת לספק את המידע למחלקה אחרת, מתי אני מחזיר את התכונה ומתי אני מחזיר עותק ?

במילים אחרות, מתי אני כותב בכל אחת מהדרכים האלו ?

public String getFirstName (){
return this.firstName;
}


public String getFirstName (){
String copyFirstName = this.firstName;
return copyFirstName;
}

תודה לכולם, ד"א אני כותב ב JAVA אם זה משנה

קישור לתוכן
שתף באתרים אחרים

שני המימושים עושים את אותו הדבר בדיוק.

השמה של אובייקטים לא גורמת להעתקה. למעשה, כשעושים השמה כזו:

String x = "abc";
String y = x;

אז x ו-y הם לא שתי מחרוזות שונות - אלה שני משתנים שמצביעים לאותה המחרוזת.

הפעולה הזו:

String copyFirstName = this.firstName;

לא יוצרת מחרוזת חדשה - היא רק יוצרת משתנה חדש שמצביע לאותה מחרוזת קיימת.

על מנת ליצור אובייקט חדש, צריך להשתמש בבנאי מעתיק. כלומר:

String copyFirstName = new String(this.firstName);

יש מבין?

נ.ב. בג'אווה, מחרוזות הן Immutable, כלומר אי אפשר לשנות אותן. לכן, אין צורך להחזיר עותק של המחרוזת, כי בין כה וכה המשתמש לא יוכל לשנות אותה. אבל אם הפונקציה שלך הייתה מחזירה אובייקט מטיפוס אחר (שכן אפשר לשנות אותו), אז יש הבדל בין החזרת האובייקט והחזרת עותק שלה.

קישור לתוכן
שתף באתרים אחרים

הבנתי תודה.

אני צריך עוד עזרה בבנית שיטה, יש לי את המחלקה Entry (שבניתי) ואני צריך לבנות את המחלקה PhoneBook ואני תקוע בבנייה של אחת השייטות במחלקה PhoneBook .

זו המחלקה Entry :

public class Entry
{
private String firstName;
private String lastName;
private String phoneNumber;

public Entry (String firstName, String lastName, String phoneNumber){
this.firstName = firstName;
this.lastName = lastName;
this.phoneNumber = phoneNumber;
}

public Entry (Entry otherEntry){
this.firstName = otherEntry.firstName;
this.lastName = otherEntry.lastName;
this.phoneNumber = otherEntry.phoneNumber;
}

public void setFirstName (String firstName){
this.firstName = firstName;
}
public void setLastName (String lastName){
this.lastName = lastName;
}
public void setPhoneNumber (String phoneNumber){
this.phoneNumber = phoneNumber;
}
public String getFirstName (){
return this.firstName;
}
public String getLastName (){
return this.lastName;
}
public String getPhoneNumber (){
return this.phoneNumber;
}
public boolean equals (Entry otherEntry){
if ((this.firstName==otherEntry.firstName)&&(this.lastName==otherEntry.lastName)){
return true;
}
return false;
}
public String toString(){
return ("First name:"+this.firstName +"\n"+ "Last name:"+this.lastName +"\n"+ "Telephone number:" + this.phoneNumber);
}

וזו המחלקה PhoneBook (רק ההתחלה כמובן - שיטה-בונה היוצרת ספר טלפונים בגודל נתון):

public class PhoneBook
{
public PhoneBook (int size){
Entry[] arr = new Entry[size];
}
public boolean addEntry (Entry entry){

}
}

}

במחלקה הזו אני צריך לבנות שיטה שמוסיפה רשומה לספר טלפונים במצב נתון:

אם הרשומה אינה קיימת - היא תתווסף למקום פנוי בספר.

אם הרשומה כבר קיימת (רשומה עם שם פרטי ושם משפחה זהה) = אז היא תוחלף ברשומה חדשה באותו מקום.

אם הרושמה הוספה או עודכנה השיטה מחזירה true , אחרת היא מחזירה false .

אני יודע שאני צריך לסרוק את המערך של הרשומות אבל אין לי מושג איך לעשות את זה בפועל גם מבחינה טכנית של רשימת הפוקודות, נגיד איך אני עושה את הלולאה עד סוף גודל המערך.

תודה

קישור לתוכן
שתף באתרים אחרים

קודם כל, יש לך טעות קטנה - אתה מצהיר על arr כמשתנה מקומי בתוך הבנאי, ולכן הוא יושמד ברגע שהבנאי יסתיים.

arr צריך להיות איבר של המחלקה.

חוץ מזה, לא הבנתי מה הבעיה. תעשה לולאה שעוברת על כל ה-Entries במערך, ובודקת כל אחד מהם אם הוא מתאים ל-Entry שאתה רוצה להכניס.

קישור לתוכן
שתף באתרים אחרים

ככה ?


public class PhoneBook
{
private Entry[] phoneBook;

public PhoneBook (int size){
this.phoneBook = new Entry[size];
}

וזה בתהליכים:

	public boolean addEntry (Entry entry){
for (int i=0; i<this.phoneBook.length; i++){
if (this.phoneBook[i].equals(entry)){
if((this.phoneBook[i].getPhoneNumber())==(entry.getPhoneNumber())){


}
}

}
}


עריכה:

לא מצליח לעשות את הלולאה :nixweiss:

הגעתי לזה ונתקעתי :pissed:

public boolean addEntry (Entry entry){
for (int i=0; i<this.phoneBook.length; i++){
if (this.phoneBook[i].equals(entry)){
if((this.phoneBook[i].getPhoneNumber())==(entry.getPhoneNumber())){
return false;
}
else{
this.phoneBook[i]=new Entry(entry);
}
}

}
}

קישור לתוכן
שתף באתרים אחרים

אוקי, הלולאה הזו נראית טוב - טיפלת במקרה שכבר יש רשומה מתאימה ברשימה (שים לב שאתה צריך לעשות return true אם כן שינית את הרשומה).

עכשיו, תחשוב מה יקרה אם לא מצאת שום רשומה מתאימה ברשימה - אז אתה צריך למצוא תא ריק, ולהוסיף את הרשומה שם.

אגב, לא חייבים להשתמש ב-this כל פעם שניגשים לאיבר של המחלקה. משתמשים ב-this רק כשיכול להיווצר כפל משמעות (נניח, כשיש פרמטר עם אותו שם כמו האיבר במחלקה).

קישור לתוכן
שתף באתרים אחרים

עכשיו, תחשוב מה יקרה אם לא מצאת שום רשומה מתאימה ברשימה - אז אתה צריך למצוא תא ריק, ולהוסיף את הרשומה שם.

זאת הבעיה שלי שאני לא מוצא את הדרך לעשות את זה !!! כי אני צריך "לסרוק את כולם" ורק אם כולם לא תואמים להוסף אותו באחד הפנוי ....

קישור לתוכן
שתף באתרים אחרים

תא ריק זה null לא ?!

אבל מה זה אומר לי, אני לומד לבד ולא מוסבר על זה כל כך בספר ...

חשבתי על משהו, אם הכוונה בתרגיל היא שאין תאים פנויים באמצע, כאילו יש רק תאים מלאים ובסוף התאים הריקים ולא 3 מלאים ואחד ריק ואז 5 מלאים לדוגמא...

אז אפשר לעשות לולאה שאם התא שווה ל null הוא יוסיף את הרשומה ויחזיר flase ואז יצא מהשיטה כך שהוא לא יוסיף אותו בכל הריקים .

זה נכון ?!

קישור לתוכן
שתף באתרים אחרים

דוד היקר , חבל שאתה מסתבך -- תנסה לחשוב על זה רגע בצורה מופשטת

נגיד הייתי אומר לך שיש לי ארונית ובה תאים רבים.

בכל תא יש מגזין אחד בלבד מכל סוג, כלומר - המגזין "בלייזר" יכול להופיע רק פעם אחת בארונית.

אם כבר קיים מגזין מסוג כלשהו בארונית, ואתה מנסה להוסיף מגזין מאותו סוג, המגזין החדש יחליף את הישן, ואת הישן נזרוק.

אם הוא לא נמצא כבר - אז נכניס את המגזין החדש בתא הראשון הפנוי.

ברור לך שכדי לעשות את זה (במציאות) צריך קודם לעבור על כל התאים לפחות פעם אחת (כי הם לא ממויינים, ולכן אין לנו אפשרות לדעת בשום שלב האם בתאים הנותרים לא קיים מגזין מהסוג שאנחנו רוצים להכניס). נכון?

עכשיו נגיד עשית את זה (וגם בקוד עשית את זה נכון) --

איך תכניס לתא הראשון הריק? אני מדבר איתך על המציאות.

כנראה שמה שתעשה זה תלך שוב מההתחלה ותנסה לחפש תא ריק, נכון?

כנ"ל לגבי הקוד.

אם אתה רוצה להפוך את זה ליותר יעיל - זה כבר סיפור אחר, ואז אפשר לדוגמא לשמור על המערך ממויין, או במקום לחפש את התא "הראשון הריק" דווקא, אפשר להכניס לתא "הריק הראשון שמוצאים", או "לזכור תא ריק שראינו בדרך". כל מיני שטויות, בקיצור.

אבל מה שתיארתי קודם נקרא "הפתרון הנאיבי" - והוא קיים כמעט עבור כל בעיה שיש לה פתרון.

הדרך הכי טובה לחשוב עליו היא: "הדרך הכי פשוטה והכי פחות מתוחכמת לבצע את המשימה ללא התחשבות ביעילות, בזבוז משאבים וכו'".

קישור לתוכן
שתף באתרים אחרים

הקוד שכתבת עד עכשיו - סבבה. רק שים לב שאתה צריך לעשות גם return true אם שינית את התוכן של תא כלשהו.

נניח שהלולאה הסתיימה, בלי שעשית return. מה זה אומר? שלא מצאת שום תא שמכיל את הרשומה, אז צריך למצוא תא ריק.

אז תעבור בלולאה נוספת (אחרי הלולאה הראשונה), שבה אתה מחפש תא שמכיל null.

אם מצאת תא כזה - שים בו את הרשומה, וצא (עם return). יש?

קישור לתוכן
שתף באתרים אחרים

בהמשך למה שעמיתי המלומד שניצל אמר - ובתגובה לשאלה שלך --

כן, מיד אחרי הוספת האיבר לתא ריק - אתה צריך לצאת מהלולאה, אחרת, כמו שאמרת - היא "תוסיף אותו לכל התאים הריקים".

שים רק לב שכמו ששניצל אמר מדובר על לולאה *נוספת* (אם עברת על כל התאים ולא מצאת רשומה דומה, תצטרך לעבור שוב מהתחלה ולחפש תאים ריקים). אתה לא יכול לעשות את זה "על הדרך" כחלק מהלולאה הראשונה כי כמו שאמרת בעצמך - אתה לא יכול להוסיף רשומה חדשה לפני שסיימת לעבור על כל האיברים.

בגלל שהיציאה מהלולאה הראשונה (של החיפוש) תבוצע ע"י RETURN, אין לך מה לדאוג לגבי הגעה ללואה השניה שלא-לצורך (כלומר, אם מצאנו איבר מתאים, אז החזרנו TRUE ויצאנו, אם לא מצאנו, נמשיך ללואה השניה).

קישור לתוכן
שתף באתרים אחרים

  • 2 שבועות מאוחר יותר...

היי,

היה לי כמה מבחנים ולא הספקתי לשבת על התרגיל הזה.

עכשיו רשמתי את הקוד הבא שאני חושב שהוא טוב, רק תאשרו לי בבקשה ;)

public boolean addEntry (Entry entry){
for (int i=0; i<this.phoneBook.length; i++){
if (this.phoneBook[i].equals(entry)){
if((this.phoneBook[i].getPhoneNumber())==(entry.getPhoneNumber())){
return false;
}
else{
this.phoneBook[i]=new Entry(entry);
return true;
}
}
}
for (int i=0; i<this.phoneBook.length; i++){
if (this.phoneBook[i]==null){
this.phoneBook[i]=new Entry (entry);
return true;
}
else{
return false;
}
}
}

קישור לתוכן
שתף באתרים אחרים

ארכיון

דיון זה הועבר לארכיון ולא ניתן להוסיף בו תגובות חדשות.

×
  • צור חדש...