תוכנה 1 בשפת Java שיעור מספר 3: "מחלקות וטיפוסים"

Slides:



Advertisements
Similar presentations
תוכנה 1 בשפת ג'אווה אוניברסיטת תל אביב
Advertisements

ממיבחניםC שאלות ++.
תוכנה 1 סמסטר א ' תשע " ב תרגול מס ' 7 * מנשקים, דיאגרמות וביטים * לא בהכרח בסדר הזה.
בתרגול הקודם הורשה: –ניתן להרחיב רק מחלקה אחת –כל מה שלא private – עובר בהורשה –המילה השמורה super –יצירת היררכיה –Object היא שורש ההיררכיה –דריסה אופרטור.
1 Formal Specifications for Complex Systems (236368) Tutorial #4 Refinement in Z: data refinement; operations refinement; their combinations.
האוניברסיטה העברית בירושלים
תכנות מונחה עצמים Object Oriented Programming (OOP) אתגר מחזור ב'
שאלות חזרה לבחינה. שאלה דיסקים אופטיים מסוג WORM (write-once-read-many) משמשים חברות לצורך איחסון כמויות גדולות של מידע באופן קבוע ומבלי שניתן לשנותו.
1 Formal Specifications for Complex Systems (236368) Tutorial #5 Refinement in Z: data refinement; operations refinement; their combinations.
מבוא למדעי המחשב © אריק פרידמן 1 מצביעים כמערכים דוגמה.
Formal Specifications for Complex Systems (236368) Tutorial #6 appendix Statecharts vs. Raphsody 7 (theory vs. practice)
חלון הפקודות מיועד לבצע פעולה אחת בכל פעם. כיצד אפשר לבצע רשימת פקודות או אפליקציות מורכבות ?
1 מבוא למדעי המחשב מבנה של תכנית. 2 מבנה של תכנית – חלוקה לקבצים  תכנית בשפת C הינה אוסף של הגדרות של:  משתנים (חיצוניים)  פונקציות  ניתן לפרוש תכנית.
תכנות תרגול 6 שבוע : תרגיל שורש של מספר מחושב לפי הסדרה הבאה : root 0 = 1 root n = root n-1 + a / root n-1 2 כאשר האיבר ה n של הסדרה הוא קירוב.
אתחולים ובנאים יצירת מופע חדש של עצם כוללת : הקצאת זכרון, אתחול, הפעלת בנאים והשמה לשדות במסגרת ריצת הבנאי נקראים גם הבנאי / ים של מחלקת הבסיס תהליך זה.
11 Introduction to Programming in C - Fall 2010 – Erez Sharvit, Amir Menczel 1 Introduction to Programming in C תרגול
תוכנה 1 בשפת Java שיעור מספר 1: מתחילים מחדש
מערכים עד היום כדי לייצג 20 סטודנטים נאלצנו להגדיר עד היום כדי לייצג 20 סטודנטים נאלצנו להגדיר int grade1, grade2, …, grade20; int grade1, grade2, …, grade20;
עקרון ההכלה וההדחה.
תכנות מונחה עצמים Object Oriented Programming (OOP) אתגר מחזור ב' Templates תבניות.
© המרכז להוראת המדעים האוניברסיטה העברית בירושלים
מתמטיקה בדידה תרגול 2.
11 Introduction to Programming in C - Fall 2010 – Erez Sharvit, Amir Menczel 1 Introduction to Programming in C תרגול
אתחול עצמים. אתחולים ובנאים יצירת מופע חדש של עצם כוללת: הקצאת זכרון, אתחול, הפעלת בנאים והשמה לשדות במסגרת ריצת הבנאי נקראים גם הבנאי/ם של מחלקת הבסיס.
תוכנה 1 בשפת Java נושאים שונים בהורשה רובי בוים ומתי שמרת בית הספר למדעי המחשב אוניברסיטת תל אביב.
ניתוח מערכות מידע ב נעים להכיר... תכנות ב C#.
פיתוח מערכות מידע Class diagrams Aggregation, Composition and Generalization.
Methods public class Demonstrate { public static void main (String argv[]) { public static void main (String argv[]) { int script = 6, acting = 9, directing.
מבוא למדעי המחשב לתעשייה וניהול הרצאה 7. סברוטינות subroutines.
Practice session 3.  תחביר ממשי ( קונקרטי ) ותחביר מופשט ( אבסטרקטי )  שיטות חישוב : Applicative & Normal Evaluation.
 Client, Supplier ומה שביניהם ( ADT!).  שאלה 1: יצירת ADT עבור מעגל במישור נניח שלקוח מעוניין בפעולות הבאות : הזזת מעגל וחישוב שטח מעגל. הספק יספק ללקוח.
תכנות מכוון עצמים ושפת ++C וויסאם חלילי. TODAY TOPICS: 1. Function Overloading & Default Parameters 2. Arguments By Reference 3. Multiple #include’s 4.
מבנים קרן כליף. ביחידה זו נלמד :  מהו מבנה (struct)  איתחול מבנה  השמת מבנים  השוואת מבנים  העברת מבנה לפונקציה  מבנה בתוך מבנה  מערך של מבנים.
1 תרגול 11: Design Patterns ומחלקות פנימיות אסף זריצקי ומתי שמרת 1 תוכנה 1.
1 נתבונן בפונקציה הבאה public static int min(int[] a,int n) { int min = a[0]; for (int i = 1; (i < n ) && (i < a.length) ; i++) if (min > a[i]) min = a[i];
תוכנה 1 בשפת Java תרגול מספר 9: נושאים שונים בהורשה אסף זריצקי ומתי שמרת בית הספר למדעי המחשב אוניברסיטת תל אביב.
עקרונות תכנות מונחה עצמים תרגול 11: OOP in C++. Outline  Where do the objects live ?  Inheritance  Slicing  Overriding vs Shadowing.
מחרוזות – הטיפוס String
האוניברסיטה העברית בירושלים
תרגול 7: מנשקים, פולימורפיזם ועוד
מספרים אקראיים ניתן לייצר מספרים אקראיים ע"י הפונקציה int rand(void);
Operators Overloading
Formal Specifications for Complex Systems (236368) Tutorial #1
Object Oriented Programming
תרגול 7: מנשקים, פולימורפיזם ועוד
מחלקות classes.
מבוא לתכנות מונחה עצמים Object Oriented Programming
תוכנה 1 תרגול 13 – סיכום.
מצביעים קרן כליף.
SQL בסיסי – הגדרה אינדוקטיבית
תוכנה 1 בשפת Java שיעור מספר 2: זרימת הבקרה
תכנות מכוון עצמים ושפת JAVA
Static and enum קרן כליף.
תכנות מכוון עצמים בשפת JAVA
ממשקים - interfaces איך לאפשר "הורשה מרובה".
תוכנה 1 בשפת Java שיעור מספר 2: "תזרום אח שלו"
תרגול מס' 6 מחלקות, עצמים, וקצת חוזים
תוכנה 1 בשפת Java שיעור מספר 5: "זרוק לו עצם"
תוכנה 1 בשפת Java שיעור מספר 8: "ירושה נכונה" (הורשה II)
ניתוח מערכות מידע תכנות ב C#
תכנות מכוון עצמים ושפת JAVA
תכנות מכוון עצמים ושפת JAVA
סוגי משתנים קרן כליף.
תוכנה 1 בשפת Java שיעור מספר 3: מודל הזיכרון ושירותים
מבוא לתכנות מונחה עצמים Object Oriented Programming
Shell Scripts בסביבת UNIX
תוכנה 1 תרגול 13 – סיכום.
תוכנה 1 תרגול 13 – סיכום.
Engineering Programming A
פולימורפיזם מתקדם ממשקים בC# עריכה ועיצוב: קרן הרדי
Presentation transcript:

תוכנה 1 בשפת Java שיעור מספר 3: "מחלקות וטיפוסים" בית הספר למדעי המחשב אוניברסיטת תל אביב

על סדר היום מודל הזיכרון של Java מנגנוני שפת Java עצמים ושירותי מופע Heap and Stack העברת ארגומנטים מנגנוני שפת Java עצמים ושירותי מופע תוכנה 1 בשפת Java אוניברסיטת תל אביב

ב Java גם reference מועבר by value העברת ארגומנטים כאשר מתבצעת קריאה לשרות, ערכי הארגומנטים נקשרים לפרמטרים הפורמליים של השרות לפי הסדר, ומתבצעת השמה לפני ביצוע גוף השרות. בהעברת ערך לשרות הערך מועתק לפרמטר הפורמלי צורה זאת של העברת פרמטרים נקראת call by value כאשר הארגומנט המועבר הוא הפנייה (התייחסות, reference) העברת הפרמטר מעתיקה את ההתייחסות. בשפות תכנות אחרות ניתן לבצע העברה של המצביע עצמו דוגמא: קבלת צילום של בחינה ממזכירות בחינות ושינוי הצילום ב Java גם reference מועבר by value תוכנה 1 בשפת Java אוניברסיטת תל אביב

העברת פרמטרים by value העברת פרמטרים by value (ע"י העתקה) יוצרת מספר מקרים מבלבלים, שידרשו מאיתנו הכרות מעמיקה יותר עם מודל הזיכרון של Java למשל, מה מדפיס הקוד הבא? public class CallByValue { public static void setToFive(int arg){ arg = 5; } public static void main(String[] args) { int x = 0; System.out.println("Before: x=" + x); setToFive(x); System.out.println("After: x=" + x); מודל הזכרון – מכיוון ש Java רצה על מכונה וירטולית, לא ברור איך נראה הזכרון באמת תוכנה 1 בשפת Java אוניברסיטת תל אביב

מודל הזיכרון של Java STACK HEAP משתנים מקומיים וארגומנטים – כל מתודה משתמשת באזור מסוים של המחסנית משתנים גלובלים ועצמים – אינו תלוי במתודה הנוכחית שרצה קוד התוכנית CODE תוכנה 1 בשפת Java אוניברסיטת תל אביב

Primitives by value public class CallByValue { public static void setToFive(int arg){ arg = 5; } public static void main(String[] args) { int x = 0; System.out.println("Before: x=" + x); setToFive(x); System.out.println("After: x=" + x); STACK HEAP println משתנים מקומיים וארגומנטים – כל מתודה משתמשת באזור מסוים של המחסנית משתנים גלובלים ועצמים – אינו תלוי במתודה הנוכחית שרצה main x “Before: x=0” [ ] args CODE תוכנה 1 בשפת Java אוניברסיטת תל אביב

Primitives by value STACK HEAP arg 5 x “Before: x=0” [ ] args CODE public class CallByValue { public static void setToFive(int arg){ arg = 5; } public static void main(String[] args) { int x = 0; System.out.println("Before: x=" + x); setToFive(x); System.out.println("After: x=" + x); STACK HEAP setToFive arg 5 main x “Before: x=0” [ ] args CODE לאחר ש setToFive מסיימת את ריצתה המקום שהוקצה עבורה על ה- Stack משוחרר לאחר ש println מסיימת את ריצתה המקום שהוקצה עבורה על ה- Stack משוחרר תוכנה 1 בשפת Java אוניברסיטת תל אביב

Primitives by value STACK HEAP “After: x=0” x “Before: x=0” [ ] args public class CallByValue { public static void setToFive(int arg){ arg = 5; } public static void main(String[] args) { int x = 0; System.out.println("Before: x=" + x); setToFive(x); System.out.println("After: x=" + x); STACK HEAP println “After: x=0” main x “Before: x=0” [ ] args CODE לאחר ש main מסיימת את ריצתה המקום שהוקצה עבורה על ה- Stack משוחרר לאחר ש println מסיימת את ריצתה המקום שהוקצה עבורה על ה- Stack משוחרר תוכנה 1 בשפת Java אוניברסיטת תל אביב

שמות מקומיים בדוגמא ראינו כי הפרמטר הפורמלי arg קיבל את הערך של הארגומנט x בחירת השמות השונים אינה משמעותית - יכולנו לקרוא לשני המשתנים באותו שם ולקבל התנהגות זהה שם של משתנה מקומי מסתיר משתנים בשם זהה הנמצאים בתחום עוטף או גלובלים נראה את ההתנהגות הזו בהמשך השיעור, בדוגמא של בנאים. מתודה מכירה רק משתני מחסנית הנמצאים באזור שהוקצה לה על המחסנית (frame) תוכנה 1 בשפת Java אוניברסיטת תל אביב

מה יקרה אם המשתנה המקומי x שהועבר היה מטיפוס הפנייה import java.util.Arrays; //explained later... public class CallByValue { public static void setToZero(int [] arr){ arr = new int[3]; } public static void main(String[] args) { int [] arr = {4,5}; System.out.println("Before: arr=" + Arrays.toString(arr)); setToZero(arr); System.out.println("After: arr=" + Arrays.toString(arr)); תוכנה 1 בשפת Java אוניברסיטת תל אביב

Reference by value STACK HEAP “[4,5]” arr args [ ] CODE Arrays.toString “[4,5]” public class CallByValue { public static void setToZero(int [] arr){ arr = new int[3]; } public static void main(String[] args) { int [] arr = {4,5}; System.out.println("Before: arr=" + Arrays.toString(arr)); setToZero(arr); System.out.println("After: arr=" + Arrays.toString(arr)); 4 5 main arr args [ ] CODE תוכנה 1 בשפת Java אוניברסיטת תל אביב

Reference by value STACK HEAP “[4,5]” “Before: arr=” main arr args [ ] println “[4,5]” public class CallByValue { public static void setToZero(int [] arr){ arr = new int[3]; } public static void main(String[] args) { int [] arr = {4,5}; System.out.println("Before: arr=" + Arrays.toString(arr)); setToZero(arr); System.out.println("After: arr=" + Arrays.toString(arr)); 4 “Before: arr=” 5 main arr “Before: arr= [4,5]” args [ ] CODE תוכנה 1 בשפת Java אוניברסיטת תל אביב

Reference by value STACK HEAP “[4,5]” arr “Before: arr=” arr args [ ] setToZero “[4,5]” public class CallByValue { public static void setToZero(int [] arr){ arr = new int[3]; } public static void main(String[] args) { int [] arr = {4,5}; System.out.println("Before: arr=" + Arrays.toString(arr)); setToZero(arr); System.out.println("After: arr=" + Arrays.toString(arr)); 4 arr “Before: arr=” 5 main arr “Before: arr= [4,5]” args [ ] CODE תוכנה 1 בשפת Java אוניברסיטת תל אביב

Reference by value STACK HEAP “[4,5]” “[4,5]” “Before: arr=” arr args Arrays.toString “[4,5]” public class CallByValue { public static void setToZero(int [] arr){ arr = new int[3]; } public static void main(String[] args) { int [] arr = {4,5}; System.out.println("Before: arr=" + Arrays.toString(arr)); setToZero(arr); System.out.println("After: arr=" + Arrays.toString(arr)); 4 “Before: arr=” 5 main arr “Before: arr= [4,5]” args [ ] CODE תוכנה 1 בשפת Java אוניברסיטת תל אביב

Reference by value STACK HEAP “[4,5]” “[4,5]” “After: arr=” println “[4,5]” public class CallByValue { public static void setToZero(int [] arr){ arr = new int[3]; } public static void main(String[] args) { int [] arr = {4,5}; System.out.println("Before: arr=" + Arrays.toString(arr)); setToZero(arr); System.out.println("After: arr=" + Arrays.toString(arr)); 4 “After: arr=” “Before: arr=” 5 “After: arr= [4,5]” main arr “Before: arr= [4,5]” args [ ] CODE תוכנה 1 בשפת Java אוניברסיטת תל אביב

הפונקציה הנקראת והעולם שבחוץ בשיטת העברה by value לא יעזור למתודה לשנות את הארגומנט שקיבלה, מכיוון שהיא מקבלת עותק אז איך יכולה מתודה להשפיע על ערכים במתודה שקראה לה? ע"י ערך מוחזר ע"י גישה למשתנים או עצמים שהוקצו ב- Heap מתודות שמשנות את תמונת הזיכרון נקראות בהקשרים מסוימים Mutators או Transformers תוכנה 1 בשפת Java אוניברסיטת תל אביב

מה מדפיסה התוכנית הבאה? public class CallByValue { static int global = 4; public static int increment(int [] arr){ int local = 5; arr[0]++; global++; return local; } public static void main(String[] args) { int [] arr = {4}; System.out.println("Before:\narr[0]=" + arr[0] + "\nglobal=" + global); int result = increment(arr); System.out.println("After:\narr[0]=" + arr[0] + System.out.println("result = " + result); תוכנה 1 בשפת Java אוניברסיטת תל אביב

STACK HEAP [ ] CODE println main 4 arr args 4 תוכנה 1 בשפת Java public class CallByValue { static int global = 4; public static int increment(int [] arr){ int local = 5; arr[0]++; global++; return local; } public static void main(String[] args) { int [] arr = {4}; System.out.println("Before:\narr[0]=" + arr[0] + "\nglobal=" + global); int result = increment(arr); System.out.println("After:\narr[0]=" + arr[0] + "\nglobal=" + global); System.out.println("result = " + result); 4 main Before: arr[0]=4 global=4 arr CallByValue.global [ ] args 4 CODE תוכנה 1 בשפת Java אוניברסיטת תל אביב

STACK HEAP [ ] CODE increment main 5 local arr 4 5 result 5 arr args 4 After: arr[0]=5 global=5 public class CallByValue { static int global = 4; public static int increment(int [] arr){ int local = 5; arr[0]++; global++; return local; } public static void main(String[] args) { int [] arr = {4}; System.out.println("Before:\narr[0]=" + arr[0] + "\nglobal=" + global); int result = increment(arr); System.out.println("After:\narr[0]=" + arr[0] + "\nglobal=" + global); System.out.println("result = " + result); 4 5 main result 5 Before: arr[0]=4 global=4 arr CallByValue.global [ ] args 4 5 CODE תוכנה 1 בשפת Java אוניברסיטת תל אביב

STACK HEAP [ ] CODE println main 5 result 5 arr args 5 After: arr[0]=5 global=5 public class CallByValue { static int global = 4; public static int increment(int [] arr){ int local = 5; arr[0]++; global++; return local; } public static void main(String[] args) { int [] arr = {4}; System.out.println("Before:\narr[0]=" + arr[0] + "\nglobal=" + global); int result = increment(arr); System.out.println("After:\narr[0]=" + arr[0] + "\nglobal=" + global); System.out.println("result = " + result); 5 main result 5 Before: arr[0]=4 global=4 arr CallByValue.global [ ] args 5 CODE תוכנה 1 בשפת Java אוניברסיטת תל אביב

Heap, Heap – Hooray! STACK HEAP [ ] CODE println main 5 5 result 5 arr After: arr[0]=5 global=5 public class CallByValue { static int global = 4; public static int increment(int [] arr){ int local = 5; arr[0]++; global++; return local; } public static void main(String[] args) { int [] arr = {4}; System.out.println("Before: arr[0]=" + arr[0] + "\tglobal=" + global); int result = increment(arr); System.out.println("After: arr[0]=" + arr[0] + "\tglobal=" + global); System.out.println("result = " + result); 5 main result 5 Before: arr[0]=4 global=4 arr CallByValue.global [ ] args 5 CODE תוכנה 1 בשפת Java אוניברסיטת תל אביב

משתני פלט (Output Parameters) איך נכתוב פונקציה שצריכה להחזיר יותר מערך אחד? הפונקציה תחזיר מערך ומה אם הפונקציה צריכה להחזיר נתונים מטיפוסים שונים? הפונקציה תקבל כארגומנטים הפניות לעצמים שהוקצו ע"י הקורא לפונקציה (למשל הפניות למערכים), ותמלא אותם בערכים משמעותיים ומה קורה אם נרצה שהפונקציה לא תחזיר ערך במקרים מסויימים? החל מ Java 8 – המחלקה Optional עוזרת לדמות את ההתנהגות הרצויה, נראה אותה בהמשך הקורס. אנלוגיה: הלקוח מעביר תבנית ביצים ומקבל אותה חזרה מלאה תוכנה 1 בשפת Java אוניברסיטת תל אביב

גושי אתחול סטטיים ראינו כי אתחול המשתנה הסטטי התרחש מיד לאחר טעינת המחלקה לזיכרון, עוד לפני פונקצית ה main ניתן לבצע פעולות נוספות (בדרך כלל אתחולים למניהם) מיד לאחר טעינת המחלקה לזיכרון, פעולות אלו יש לציין בתוך בלוק static פרטים נוספים: https://docs.oracle.com/javase/tutorial/java/javaOO/initial.html תוכנה 1 בשפת Java אוניברסיטת תל אביב

תמונת הזיכרון האמיתית מודל הזיכרון שתואר כאן הוא פשטני – פרטים רבים נוספים נשמרים על המחסנית וב- Heap תמונת הזיכרון האמיתית והמדויקת היא תלוית סביבה ועשויה להשתנות בריצות בסביבות השונות נושא זה נידון בהרחבה בקורס "קומפילציה" תוכנה 1 בשפת Java אוניברסיטת תל אביב

המחלקה כספריה של שרותים תוכנה 1 בשפת Java אוניברסיטת תל אביב

המחלקה כספריה של שרותים ניתן לראות במחלקה ספריה של שרותים, מודול: אוסף של פונקציות עם מכנה משותף רוב המחלקות ב Java, נוסף על היותן ספריה, משמשות גם כטיפוס נתונים. ככאלו הן מכילות רכיבים נוספים פרט לשרותי מחלקה. נדון במחלקות אלו בהמשך השיעור ואולם קיימות ב- Java גם כמה מחלקות המשמשות כספריות בלבד. בין השימושיות שבהן: java.lang.Math java.util.Arrays java.lang.System תוכנה 1 בשפת Java אוניברסיטת תל אביב

חבילות ומרחב השמות מרחב השמות של Java הוא היררכי בדומה לשמות תיקיות במערכת הקבצים חבילה (package) יכולה להכיל מחלקות או תת-חבילות בצורה רקורסיבית שמה המלא של מחלקה (fully qualified name) כולל את שמות כל החבילות שהיא נמצאת בהן מהחיצונית ביותר עד לפנימית. שמות החבילות מופרדים בנקודות מקובל כי תוכנה הנכתבת בארגון מסוים משתמש בשם התחום האינטרנטי של אותו ארגון כשם החבילות העוטפות תוכנה 1 בשפת Java אוניברסיטת תל אביב

חבילות ומרחב השמות קיימת התאמה בין מבנה התיקיות (directories, folders) בפרויקט תוכנה ובין חבילות הקוד (packages) תוכנה 1 בשפת Java אוניברסיטת תל אביב

חבילות ומרחב השמות כיצד נריץ תוכנית אשר נמצאת ב package כלשהו? ב eclipse ב command line תוכנה 1 בשפת Java אוניברסיטת תל אביב

משפט import שימוש בשמה המלא של מחלקה מסרבל את הקוד: System.out.println("Before: x=" + java.util.Arrays.toString(arr)); ניתן לחסוך שימוש בשם מלא ע"י ייבוא השם בראש הקובץ (מעל הגדרת המחלקה) import java.util.Arrays; ... System.out.println("Before: x=" + Arrays.toString(arr)); תוכנה 1 בשפת Java אוניברסיטת תל אביב

משפט import כאשר עושים שימוש נרחב במחלקות מחבילה מסויימת ניתן לייבא את שמות כל המחלקות במשפט import יחיד: import java.util.*; ... System.out.println("Before: x=" + Arrays.toString(arr)); השימוש ב-* אינו רקורסיבי, כלומר יש צורך במשפט import נפרד עבור כל תת חבילה: // for classes directly under subpackage import package.subpackage.*; // for classes directly under subsubpackage1 import package.subpackage.subsubpackage1.*; // only for the class SomeClass import package.subpackage.subsubpackage2.SomeClass; תוכנה 1 בשפת Java אוניברסיטת תל אביב

משפט static import החל מ Java5 ניתן לייבא למרחב השמות את השרות או המשתנה הסטטי (static import) ובכך להימנע מציון שם המחלקה בגוף הקוד: package il.ac.tau.cs.software1.examples; import static il.ac.tau.cs.software1.examples.SomeOtherClass.someMethod; public class SomeClass { public static void main(String[] args) { someMethod(); } גם ב static import ניתן להשתמש ב- * מה קורה אם לא מכריזים על PACKAGE A compilation unit that has no package declaration is part of an unnamed package. Note that an unnamed package cannot have subpackages, since the syntax of a package declaration always includes a reference to a named top level package. As an example, the compilation unit: class FirstCall { public static void main(String[] args) { System.out.println("Mr. Watson, come here. " + "I want you."); } } defines a very simple compilation unit as part of an unnamed package.An implementation of the Java platform must support at least one unnamed package; it may support more than one unnamed package but is not required to do so. Which compilation units are in each unnamed package is determined by the host system. In implementations of the Java platform that use a hierarchical file system for storing packages, one typical strategy is to associate an unnamed package with each directory; only one unnamed package is observable at a time, namely the one that is associated with the "current working directory." The precise meaning of "current working directory" depends on the host system. Unnamed packages are provided by the Java platform principally for convenience when developing small or temporary applications or when just beginning development. תוכנה 1 בשפת Java אוניברסיטת תל אביב

הערות על מרחב השמות ב- Java שימוש במשפט import אינו שותל קוד במחלקה והוא נועד לצורכי נוחות בלבד אין צורך לייבא מחלקות מאותה חבילה אין צורך לייבא את החבילה java.lang ייבוא כוללני מדי של שמות מעיד על צימוד חזק בין מודולים ייבוא של חבילות עם מחלקות באותו שם יוצר ambiguity של הקומפיילר וגורר טעות קומפילציה ("התנגשות שמות") סביבות הפיתוח המודרניות יודעות לארגן בצורה אוטומטית את משפטי ה import כדי להימנע מייבוא גורף מדי ("name pollution") תוכנה 1 בשפת Java אוניברסיטת תל אביב

CLASSPATH איפה נמצאות המחלקות? איך יודעים הקומפיילר וה- JVM היכן לחפש את המחלקות המופיעות בקוד המקור או ה byte code? קיים משתנה סביבה בשם CLASSPATH המכיל שמות של תיקיות במערכת הקבצים שם יש לחפש מחלקות הנזכרות בתוכנית ה- CLASSPATH מכיל את תיקיות ה"שורש" של חבילות המחלקות ניתן להגדיר את המשתנה בכמה דרכים: הגדרת המשתנה בסביבה (תלוי במערכת ההפעלה) הגדרה אד-הוק – ע"י הוספת תיקיות חיפוש בשורת הפקודה (בעזרת הדגל cp או classpath) הגדרת תיקיות החיפוש בסביבת הפיתוח תוכנה 1 בשפת Java אוניברסיטת תל אביב

jar כאשר ספקי תוכנה נותנים ללקוחותיהם מספר גדול של מחלקות הם יכולים לארוז אותן כארכיב התוכנית jar (Java ARchive) אורזת מספר מחלקות לקובץ אחד תוך שמירה על מבנה החבילות הפנימי שלהן הפורמט תואם למקובל בתוכנות דומות כגון zip, tar, rar ואחרות כדי להשתמש במחלקות הארוזות אין צורך לפרוס את קובץ ה- jar ניתן להוסיפו ל CLASSPATH של התוכנית התוכנית jar היא חלק מה- JDK וניתן להשתמש בה משורת הפקודה או מתוך סביבת הפיתוח תוכנה 1 בשפת Java אוניברסיטת תל אביב

API and Javadoc קובץ ה- jar עשוי שלא להכיל קובצי מקור כלל, אלא רק קובצי class (למשל משיקולי זכויות יוצרים) איך יכיר לקוח שקיבל jar מספק תוכנה כלשהו את הפונקציות והמשתנים הנמצאים בתוך ה- jar, כדי שיוכל לעבוד איתם? בעולם התוכנה מקובל לספק ביחד עם הספריות גם מסמך תיעוד, המפרט את שמות וחתימות המחלקות, השרותים והמשתנים יחד עם תיאור מילולי של אופן השימוש בהם תוכנה בשם javadoc מחוללת תיעוד אוטומטי בפורמט html על בסיס הערות התיעוד שהופיעו בגוף קובצי המקור תיעוד זה מכונה API (Application Programming Interface) תוכנת ה javadoc היא חלק מה- JDK וניתן להשתמש בה משורת הפקודה או מתוך סביבת הפיתוח תוכנה 1 בשפת Java אוניברסיטת תל אביב

Javadoc /** Documentation for the package */ package somePackage; /** Documentation for the class * @author your name here */ public class SomeClass { /** Documentation for the class variable */ public static int someVariable; /** Documentation for the class method * @param x documentation for parameter x * @param y documentation for parameter y * @return * documentation for return value public static int someMethod(int x, int y, int z){ // this comment would NOT be included in the documentation return 0; } תוכנה 1 בשפת Java אוניברסיטת תל אביב

Javadoc כך זה ניראה ב eclipse: חלק מדף ה html שנוצר תוכנה 1 בשפת Java אוניברסיטת תל אביב

https://docs.oracle.com/javase/8/docs/api/ Java API ניתן למצוא את התיעוד של כל ספריות ה Java באמצעות javadoc באתר של חברת Oracle. https://docs.oracle.com/javase/8/docs/api/ תוכנה 1 בשפת Java אוניברסיטת תל אביב

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

מחלקות כטיפוסי נתונים תוכנה 1 בשפת Java אוניברסיטת תל אביב

מחלקות כטיפוסי נתונים ביסודה של גישת התכנות מונחה העצמים קיימת ההנחה שניתן לייצג ישויות מעולם הבעיה ע"י ישויות בשפת התכנות בכתיבת מערכת תוכנה בתחום מסוים (domain), נרצה לתאר את המרכיבים השונים באותו תחום כטיפוסים ומשתנים בתוכנית המחשב התחומים שבהם נכתבות מערכות תוכנה מגוונים: בנקאות, ספורט, תרופות, מוצרי צריכה, משחקים ומולטימדיה, פיסיקה ומדע, מנהלה, מסחר ושרותים... יש צורך בהגדרת טיפוסי נתונים שישקפו את התחום, כדי שנוכל לעלות ברמת ההפשטה שבה אנו כותבים תוכניות תוכנה 1 בשפת Java אוניברסיטת תל אביב

מחלקות כטיפוסי נתונים מחלקות מגדירות טיפוסים שהם הרכבה של טיפוסים אחרים (יסודיים או מחלקות בעצמם) מופע (instance) של מחלקה נקרא עצם (object) בשפת Java הגישה לעצמים היא באמצעות טיפוסי הפניה לעצם לא ניתן לגשת לעצם עצמו. כל מופע עשוי להכיל: נתונים (data members, instance fields) שרותים (instance methods) פונקציות אתחול (בנאים, constructors) תוכנה 1 בשפת Java אוניברסיטת תל אביב

מחלקות ועצמים כבר ראינו בקורס שימוש בטיפוסים שאינם פרימיטיביים: מחרוזת ומערך גם ראינו שעקב שכיחות השימוש בהם יש להם הקלות תחביריות מסוימות (פטור מ- new והעמסת אופרטור +) ראינו כי עבודה עם טיפוסים אלה מערבת שתי ישויות נפרדות: העצם: המכיל את המידע ההפנייה: משתנה שדרכו ניתן לגשת לעצם זאת בשונה ממשתנים יסודיים (טיפוסים פרימיטיביים) דוגמא: int i =5 , j = 7; String s = "Hello", t = "World"; i ו- j הם מופעים של int כשם ש "hello" ו- "world" הם מופעים של String. s ו t הם הפניות למחרוזות. תוכנה 1 בשפת Java אוניברסיטת תל אביב

שרותי מופע למחלקות יש שרותי מופע – פונקציות אשר מופעלות על מופע מסוים של המחלקה תחביר של הפעלת שרות מופע הוא: objRef.methodName(arguments) לדוגמא: String str = "SupercaliFrajalistic"; int len = str.length(); זאת בשונה מזימון שרות מחלקה (static): ClassName.methodName(arguments) String.valueOf(15); // returns the string “15” שימו של כי האופרטור נקודה (.) משמש בשני המקרים בתפקידים שונים לגמרי! תוכנה 1 בשפת Java אוניברסיטת תל אביב

שימוש במחלקות קיימות לטיפוס מחלקה תכונות בסיסיות, אשר סיפק כותב המחלקה, ואולם ניתן לבצע עם העצמים פעולות מורכבות יותר ע"י שימוש באותן תכונות את התכונות הבסיסיות יכול הספק לציין למשל בקובץ תיעוד תיעוד נכון יתאר מה השרותים הללו עושים ולא איך הם ממומשים התיעוד יפרט את חתימת השרותים ואת החוזה שלהם נתבונן במחלקה Turtle המייצגת צב לוגו המתקדם על משטח ציור כאשר זנבו למטה הוא מצייר קו במסלול ההתקדמות כאשר זנבו למעלה הוא מתקדם ללא ציור כותב המחלקה לא סיפק את הקוד שלה אלא רק עמוד תיעוד המתאר את הצב (המחלקה ארוזה ב JAR של קובצי class) תוכנה 1 בשפת Java אוניברסיטת תל אביב

Turtle API בנאי – פונקצית אתחול - ניתן לייצר מופעים חדשים של המחלקה ע"י קריאה לבנאי עם האופרטור new שרותים – נפריד בין 2 סוגים שונים: שרותי מחלקה – אינם מתייחסים לעצם מסוים, מסומנים static שרותי מופע – שרותים אשר מתייחסים לעצם מסוים. יופנו לעצם מסוים ע"י שימוש באופרטור הנקודה תוכנה 1 בשפת Java אוניברסיטת תל אביב

Turtle API סוגים של שרותי מופע: שאילתות (queries) – שרותים שיש להם ערך מוחזר בדרך כלל לא משנים את מצב העצם בשיעור הבא נדון בסוגים שונים של שאילתות פקודות (commands) – שרותים ללא ערך מוחזר בדרך כלל משנים את מצב העצם שעליו הם פועלים תוכנה 1 בשפת Java אוניברסיטת תל אביב

דוגמת שימוש public class TurleClient { public static void main(String[] args) { Turtle leonardo = new Turtle(); if(!leonardo.isTailDown()) leonardo.tailDown(); leonardo.moveForward(50); leonardo.turnRight(90); } תוכנה 1 בשפת Java אוניברסיטת תל אביב

עוד דוגמת שימוש public class TurleClient { public static void main(String[] args) { Turtle leonardo = new Turtle(); leonardo.tailDown(); drawSquarePattern(leonardo, 50, 10); } public static void drawSquare(Turtle t, int size) { for (int i = 0; i < 4; i++) { t.moveForward(size); t.turnRight(90); public static void drawSquarePattern(Turtle t, int size, int angle) { for (int i = 0; i < 360/angle; i++) { drawSquare(t, size); t.turnRight(angle); תוכנה 1 בשפת Java אוניברסיטת תל אביב

האם המחלקה צריכה להכיל כל שירות אפשרי? מדוע המחלקה Turtle לא הכילה מלכתחילה את השרותים drawSquare ו- drawSquarePattern ? יש לכך יתרונות וחסרונות איך לימדנו את הצב את התעלולים החדשים? נשים לב להבדל בין השירותים הסטטיים שמקבלים עצם כארגומנט ומבצעים עליו פעולות ובין שרותי המופע אשר אינם מקבלים את העצם כארגומנט מפורש (העצם מועבר מאחורי הקלעים) תוכנה 1 בשפת Java אוניברסיטת תל אביב

הגדרת טיפוסים חדשים תוכנה 1 בשפת Java אוניברסיטת תל אביב

The cookie cutter כאשר מכינים עוגיות מקובל להשתמש בתבנית ברזל או פלסטיק כדי ליצור עוגיות בצורות מעניינות (כוכבים) תבנית העוגיות (cookie cutter) היא מעין מחלקה ליצירת עוגיות העוגיות עצמן הן מופעים (עצמים) שנוצקו מאותה תבנית כאשר ה JVM טוען לזכרון את קוד המחלקה עוד לא נוצר אף מופע של אותה המחלקה. המופעים יווצרו בזמן מאוחר יותר – כאשר הלקוח של המחלקה יקרא מפורשות לאופרטור new אם יש לנו תבנית לעוגיות, זה לא אומר שיש לנו עוגיות. התבנית מגדירה את הצורה של העוגיות, אבל לא את הטעם שלהן (וניל? שוקולד?) תוכנה 1 בשפת Java אוניברסיטת תל אביב

דוגמא נתבונן במחלקה MyDate לייצוג תאריכים: public class MyDate { int day; int month; int year; } שימו לב! המשתנים day, month ו- year הוגדרו ללא המציין static ולכן בכל מופע עתידי של עצם מהמחלקה MyDate יופיעו השדות האלה שאלה: כאשר ה JVM טוען לזיכרון את המחלקה איפה בזיכרון נמצאים השדות day, month ו- year? תשובה: הם עוד לא נמצאים! הם יווצרו רק כאשר לקוח ייצר מופע (עצם, אובייקט) מהמחלקה תוכנה 1 בשפת Java אוניברסיטת תל אביב

לקוח של המחלקה MyDate לקוח של המחלקה הוא קטע קוד המשתמש ב- MyDate למשל: כנראה שמי שכותב יישום של יומן פגישות צריך להשתמש במחלקה דוגמא: public class MyDateClient { public static void main(String[] args) { MyDate d1 = new MyDate(); d1.day = 29; d1.month = 2; d1.year = 1984; System.out.println(d1.day + "/" + d1.month + "/" + d1.year); } בדוגמא אנו רואים: שימוש באופרטור ה new ליצירת מופע חדש מטיפוס MyDate שימוש באופרטור הנקודה לגישה לשדה של המופע המוצבע ע"י d1 תוכנה 1 בשפת Java אוניברסיטת תל אביב

אם שרות, אז עד הסוף האם d1.day += 7 ? האם התאריך d1 מייצג תאריך תקין? מה יעשה כותב היומן כאשר יצטרך להזיז את הפגישה בשבוע? האם d1.day += 7 ? כמו כן, אם למחלקה כמה לקוחות שונים – אזי הלוגיקה הזו תהיה משוכפלת אצל כל אחד מהלקוחות אחריותו של מי לוודא את תקינות התאריכים ולממש את הלוגיקה הנלווית? המחלקה היא גם מודול. אחריותו של הספק – כותב המחלקה – לממש את כל הלוגיקה הנלווית לייצוג תאריכים כדי לאכוף את עקביות המימוש (משתמר המחלקה) על משתני המופע להיות פרטיים תוכנה 1 בשפת Java אוניברסיטת תל אביב

בהמשך ניראה מימוש אחר של השירותים של MyData. public class MyDate { private int day; private int month; private int year; public static void incrementDate(MyDate d){ // changes d to be the consequent day } public static String toString(MyDate d){ return d.day + "/" + d.month + "/" + d.year; public static void setDay(MyDate d, int day){ /* changes the day part of d to be day if * the resulting date is legal */ public static int getDay(MyDate d){ return d.day; private static boolean isLegal(MyDate d){ // returns if d represents a legal date // more... בהמשך ניראה מימוש אחר של השירותים של MyData. במימוש זה, לא נצטרך לשלוח את d כפרמטר לשירותים. תוכנה 1 בשפת Java אוניברסיטת תל אביב

נראות פרטית מכיוון שהשדות day,month ו- year הוגדרו בנראות פרטית (private) לא ניתן להשתמש בהם מחוץ למחלקה (שגיאת קומפילציה) public class MyDateClient { public static void main(String[] args) { MyDate d1 = new MyDate(); d1.day = 29; d1.month = 2; d1.year = 1984; } כדי לשנות את ערכם יש להשתמש בשרותים הציבוריים שהוגדרו לשם כך תוכנה 1 בשפת Java אוניברסיטת תל אביב

לקוח של המחלקה MyDate השימוש בפונקציות גלובליות (סטטיות) מסורבל public class MyDateClient { public static void main(String[] args) { MyDate d1 = new MyDate(); MyDate.setDay(d1, 29); MyDate.setMonth(d1, 2); MyDate.setYear(d1, 1984); System.out.println(MyDate.toString(d1)); } כעת הדוגמא מתקמפלת אך עדיין נותרו בה שתי בעיות: השימוש בפונקציות גלובליות (סטטיות) מסורבל עבור כל פונקציה אנו צריכים להעביר את d1 כארגומנט מיד לאחר השימוש באופרטור ה new קיבלנו עצם במצב לא עיקבי עד לביצוע השמת התאריכים הוא מייצג את התאריך הלא חוקי 0/0/00 תוכנה 1 בשפת Java אוניברסיטת תל אביב

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

ממתקים להמונים ניתן לראות בשרותי מופע סוכר תחבירי (syntactic sugar) לשרותי מחלקה ניתן לדמיין את שרות המופע m() של מחלקה C כאילו היה שרות מחלקה (סטטי) המקבל עצם מהטיפוס C כארגומנט: public class C { public void m(args){ ... } public static void m(C thisObj, args) { … } תוכנה 1 בשפת Java אוניברסיטת תל אביב

ממתקים להמונים בראייה זו, הקריאות למתודה m() של לקוחות המחלקה C יתורגמו ע"י העברת ההפניה שעליה בוצעה הקריאה כארגומנט לשרות הסטטי: public class SomeClient { public static void main(String[] args) { C obj = new C(); obj.m(args); } C.m(obj,args) תוכנה 1 בשפת Java אוניברסיטת תל אביב

"לא מה שחשבת" שרותי מופע מספקים תכונה נוספת ל Java פרט לסוכר התחבירי בהמשך הקורס נראה כי לשרותי המופע ב Java תפקיד מרכזי בשיגור שרותים דינאמי (dynamic dispatch), תכונה בשפה המאפשרת החלפת המימוש בזמן ריצה ופולימורפיזם תאור שרותי מופע כסוכר תחבירי הוא פשטני (ושגוי!) אך נותן אינטואיציה טובה לגבי פעולת השרות בשלב זה של הקורס תוכנה 1 בשפת Java אוניברסיטת תל אביב

המשתנה this מוכר בתוך שרותי המופע כאילו הועבר ע"י המשתמש. public class MyDate { private int day; private int month; private int year; public static void incrementDate(MyDate d){ // changes itself to be the consequent day } public static String toString(MyDate d){ return d.day + "/" + d.month + "/" + d.year; public static void setDay(MyDate d, int day){ /* changes the day part of itself to be day if * the resulting date is legal */ public static int getDay(MyDate d){ return d.day; private static boolean isLegal(MyDate d){ // returns if the argument represents a legal date // more... הקוד הזה חוקי ! המשתנה this מוכר בתוך שרותי המופע כאילו הועבר ע"י המשתמש. אולם לא חובה להשתמש בו this. this. this. this. תוכנה 1 בשפת Java אוניברסיטת תל אביב

public void incrementDate(){ public class MyDate { private int day; private int month; private int year; public void incrementDate(){ // changes current object to be the consequent day } public String toString(){ return day + "/" + month + "/" + year; public void setDay(int day){ /* changes the day part of the current object to be day if * the resulting date is legal */ public int getDay(){ return day; private boolean isLegal(){ // returns if the current object represents a legal date // more... תוכנה 1 בשפת Java אוניברסיטת תל אביב

בנאים (constructors) כדי לפתור את הבעיה שהעצם אינו מכיל ערך תקין מיד עם יצירתו נגדיר עבור המחלקה בנאי בנאי הוא פונקצית אתחול הנקראת ע"י אופרטור ה new מיד אחרי שהוקצה מקום לעצם החדש. שמה כשם המחלקה שהיא מאתחלת וחתימתה אינה כוללת ערך מוחזר המוטיבציה המרכזית להגדרת בנאים היא יצירת עצם שהוא עקבי עם השימוש המיועד שלו (בהמשך נדבר על משתמר מחלקה ומצב מופשט בעל משמעות) למשל, נרצה שהאובייקט ה MyDate שאנחנו מייצרים יכיל תאריך חוקי מיד עם יצירתו תוכנה 1 בשפת Java אוניברסיטת תל אביב

public MyDate(int day, int month, int year) { this.day = day; public class MyDate { public MyDate(int day, int month, int year) { this.day = day; this.month = month; this.year = year; } // ... public class MyDateClient { public static void main(String[] args) { MyDate d1 = new MyDate(29,2,1984); d1.incrementDate(); System.out.println(d1.toString()); הגדרת בנאי ל MyDate קוד לקוח המשתמש ב- MyDate תוכנה 1 בשפת Java אוניברסיטת תל אביב

בנאים האם ניתן לוותר על השימוש ב this בבנאי שהגדרנו? public class MyDate { public MyDate(int day, int month, int year) { this.day = day; this.month = month; this.year = year; } כעת מופיעה בקוד ההשמה הבאה: day=day; בגלל ששם השדה זהה לשם הפרמטר, הורדת השימוש ב this מייצרת השמה חסרת משמעות אשר אינה מאתחלת את השדה day.

בנאי ברירת מחדל במידה ולא הוגדר אף בנאי למחלקה, נוצר בנאי ברירת מחדל (default constructor). בנאי ברירת המחדל מתנהג בדיוק כמו הבנאי הבא: ומאפשר יצירה של אובייקט מטיפוס MyDate באופן הבא: public class MyDate { public MyDate() { } public static void main(String[] args) { MyDate d1 = new MyDate(); }

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

בנאים האם הקוד הבא יתקמפל? public class MyDate { public MyDate(int day, int month, int year) { this.day = day; this.month = month; this.year = year; } public static void main(String[] args) { MyDate d1 = new MyDate(); בנאי ברירת מחדל נוצר רק כאשר לא הוגדר אף בנאי אחר במחלקה. אם קיים מימוש של בנאי כלשהו, הבנאי הריק לא נוצר אוטומטית ויש לממש אותו בקוד במידה ונרצה להשתמש בו.

מודל הזיכרון של זימון שרותי מופע

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

private static double numOfPoints; private double x; private double y; public class Point { private static double numOfPoints; private double x; private double y; public Point(double x, double y){ this.x = x; this.y = y; numOfPoints++; } public double getX() { return x; public void setX(double newX) { if(newX > 0.0 && newX < 100.0) doSetX(newX); public void doSetX(double newX) { x = newX; // More methods... מודל הזכרון – מכיוון ש Java רצה על מכונה וירטולית, לא ברור איך נראה הזכרון באמת תוכנה 1 בשפת Java אוניברסיטת תל אביב

PointUser public class PointUser { public static void main(String[] args) { Point p1 = new Point(1.0, 2.0); Point p2 = new Point(10.0, 20.0); p1.setX(11.0); p2.setX(21.0); System.out.println("p1.x == " + p1.getX()); } תוכנה 1 בשפת Java אוניברסיטת תל אביב

במהלך ריצת בנאי, ההפניה this מצביעה על העצם שזה עתה הוקצה בכל הפעלה של שרות מופע או בנאי יש עצם מטרה (target) שעליו הופעל השרות. ההפניה this מצביעה לעצם זה במהלך ריצת בנאי, ההפניה this מצביעה על העצם שזה עתה הוקצה Point(x,y) public class PointUser { public static void main(String[] args) { Point p1 = new Point(1.0, 2.0); Point p2 = new Point(10.0, 20.0); p1.setX(11.0); p2.setX(21.0); System.out.println("p1.x == " + p1.getX()); } STACK HEAP this Point.numOfPoints y 2.0 1 x 1.0 main p1 x 1.0 y 2.0 args [ ] CODE public class Point { public Point(double x, double y){ this.x = x; this.y = y; numOfPoints++; } public double getX() { return x; } public void setX(double newX) { if(newX > 0.0 && newX < 100.0) doSetX(newX); public void doSetX(double newX) { x = newX; } תוכנה 1 בשפת Java אוניברסיטת תל אביב

[ ] CODE this STACK HEAP y 20.0 x 10.0 main p2 p1 args Point(x,y) 1 2 public class PointUser { public static void main(String[] args) { Point p1 = new Point(1.0, 2.0); Point p2 = new Point(10.0, 20.0); p1.setX(11.0); p2.setX(21.0); System.out.println("p1.x == " + p1.getX()); } STACK HEAP y 20.0 Point.numOfPoints 2 1 x 10.0 x 10.0 y 20.0 main p2 p1 x 1.0 y 2.0 args [ ] CODE public class Point { public Point(double x, double y){ this.x = x; this.y = y; numOfPoints++; } public double getX() { return x; } public void setX(double newX) { if(newX > 0.0 && newX < 100.0) doSetX(newX); public void doSetX(double newX) { x = newX; } תוכנה 1 בשפת Java אוניברסיטת תל אביב

בזימון של שרות מופע עצם המטרה הוא העצם doSetX this בזימון של שרות מופע עצם המטרה הוא העצם שעליו הופעל השרות. ההפניה this תצביע לעצם זה ההשמה x = newX היא בעצם this.x = newX הקריאה doSetX(newX) היא בעצם this.doSetX(newX) איזה עצם הוא מטרת הקריאה? newX 11.0 public class PointUser { public static void main(String[] args) { Point p1 = new Point(1.0, 2.0); Point p2 = new Point(10.0, 20.0); p1.setX(11.0); p2.setX(21.0); System.out.println("p1.x == " + p1.getX()); } setX STACK HEAP this Point.numOfPoints 2 newX 11.0 x 10.0 y 20.0 main p2 p1 x 1.0 11.0 y 2.0 args [ ] CODE public class Point { public Point(double x, double y){ this.x = x; this.y = y; numOfPoints++; } public double getX() { return x; } public void setX(double newX) { if(newX > 0.0 && newX < 100.0) doSetX(newX); public void doSetX(double newX) { x = newX; } this.doSetX(newX); תוכנה 1 בשפת Java אוניברסיטת תל אביב { this.x = newX; }

הקריאה doSetX(newX) היא סוכר תחבירי this ההשמה x = newX היא סוכר תחבירי של this.x = newX בזימון של שרות מופע עצם המטרה הוא העצם שעליו הופעל השרות. ההפניה this תצביע לעצם זה הקריאה doSetX(newX) היא סוכר תחבירי של this.doSetX(newX) איזה עצם הוא מטרת הקריאה? newX 21.0 public class PointUser { public static void main(String[] args) { Point p1 = new Point(1.0, 2.0); Point p2 = new Point(10.0, 20.0); p1.setX(11.0); p2.setX(21.0); System.out.println("p1.x == " + p1.getX()); } setX STACK HEAP this Point.numOfPoints 2 newX 21.0 x 21.0 10.0 y 20.0 main p2 p1 x 11.0 y 2.0 args [ ] CODE public class Point { public Point(double x, double y){ this.x = x; this.y = y; numOfPoints++; } public double getX() { return x; } public void setX(double newX) { if(newX > 0.0 && newX < 100.0) doSetX(newX); public void doSetX(double newX) { x = newX; } this.doSetX(newX); תוכנה 1 בשפת Java אוניברסיטת תל אביב { this.x = newX; }

המשפט "return x" הוא בעצם "return this.x" איזה עצם הוא מטרת הקריאה? public class PointUser { public static void main(String[] args) { Point p1 = new Point(1.0, 2.0); Point p2 = new Point(10.0, 20.0); p1.setX(11.0); p2.setX(21.0); System.out.println("p1.x == " + p1.getX()); } STACK HEAP Point.numOfPoints getX this 2 x 21.0 y 20.0 “11” main p2 “p1.x == ” p1 x 11.0 y 2.0 args “p1.x == 11” [ ] CODE public class Point { public Point(double x, double y){ this.x = x; this.y = y; numOfPoints++; } public double getX() { return x; } public void setX(double newX) { if(newX > 0.0 && newX < 100.0) doSetX(newX); public void doSetX(double newX) { x = newX; } { return this.x; } תוכנה 1 בשפת Java אוניברסיטת תל אביב { this.x = newX; }

סיכום ביניים שרותי מופע (instance methods) בשונה משרותי מחלקה (static method) פועלים על עצם מסוים (this) בעוד ששרותי מחלקה פועלים בדרך כלל על הארגומנטים שלהם משתני מופע (instance fields) בשונה ממשתני מחלקה (static fields) הם שדות בתוך עצמים. הם נוצרים רק כאשר נוצר עצם חדש מהמחלקה (ע"י new) בעוד ששדות מחלקה הם משתנים גלובלים. קיים עותק אחד שלהם, שנוצר בעת טעינת קוד המחלקה לזכרון, ללא קשר ליצירת עצמים מאותה המחלקה תוכנה 1 בשפת Java אוניברסיטת תל אביב