54
ההההה1 ההההJava ההההה הההה3 : "ההההה ההההה" ףףףףף ףףףף ףףף ףףףף ףףףףף ףףףףף ףףףףףףףףףף ףף ףףףף

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

Embed Size (px)

DESCRIPTION

תוכנה 1 בשפת Java שיעור מספר 3: "חתיכת טיפוס". ליאור וולף. בית הספר למדעי המחשב אוניברסיטת תל אביב. המחלקה כספריה של שרותים. ניתן לראות במחלקה ספריה של שרותים, מודול : אוסף של פונקציות עם מכנה משותף - PowerPoint PPT Presentation

Citation preview

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

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

ליאור וולף

בית הספר למדעי המחשב

אוניברסיטת תל אביב

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

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

2

המחלקה כספריה של שרותים

אוסף ספריה של שרותים, מודולניתן לראות במחלקה :של פונקציות עם מכנה משותף

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

לשרותי מחלקה. נדון במחלקות אלו בהמשך השיעור

-ואולם קיימות בJava גם כמה מחלקות המשמשות כספריות בלבד. בין השימושיות שבהן:

java.lang.Math java.util.Arrays java.lang.System

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

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

3

חבילות ומרחב השמות

מרחב השמות שלJavaהיררכי בדומה לשמות תחומים באינטרנט או שמות תיקיות במערכת

הקבצים

( חבילהpackage יכולה להכיל מחלקות או תת-חבילות )בצורה רקורסיבית

( שמה המלא של מחלקהfully qualified name כולל את )שמות כל החבילות שהיא נמצאת בהן מהחיצונית ביותר

עד לפנימית. שמות החבילות מופרדים בנקודות

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

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

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

4

חבילות ומרחב השמות

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

(packages)

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

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

5

importמשפט

שימוש בשמה המלא של מחלקה מסרבל אתהקוד:

System.out.println("Before: x=" + java.util.Arrays.toString(arr));

ניתן לחסוך שימוש בשם מלא ע"י ייבוא השםבראש הקובץ )מעל הגדרת המחלקה(

import java.util.Arrays;...

System.out.println("Before: x=" + Arrays.toString(arr));

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

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

6

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 someClassimport package.subpackage.subsubpackage2.someClass;

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

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

7

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* -ניתן להשתמש ב

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

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

8

Javaהערות על מרחב השמות ב-

שימוש במשפטimport שותל קוד במחלקה והוא אינו נועד לצורכי נוחות בלבד

אין צורך לייבא מחלקות מאותה חבילה אין צורך לייבא את החבילהjava.lang ייבוא כוללני מדי של שמות מעיד על צימוד חזק בין

מודולים ייבוא של חבילות עם מחלקות באותו שם יוצר

ambiguity של הקומפיילר וגורר טעות קומפילציה )"התנגשות שמות"(

סביבות הפיתוח המודרניות יודעות לארגן בצורה כדי להימנע מייבוא importאוטומטית את משפטי ה

"(name pollutionגורף מדי )"

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

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

9

CLASSPATH

?איפה נמצאות המחלקות -איך יודעים הקומפיילר והJVM היכן לחפש את המחלקות המופיעות

?byte codeבקוד המקור או ה

קיים משתנה סביבה בשםCLASSPATH המכיל שמות של תיקיות במערכת הקבצים שם יש לחפש מחלקות הנזכרות בתוכנית

-הCLASSPATHמכיל את תיקיות ה"שורש" של חבילות המחלקות :ניתן להגדיר את המשתנה בכמה דרכים

)הגדרת המשתנה בסביבה )תלוי במערכת ההפעלה הגדרה אד-הוק – ע"י הוספת תיקיות חיפוש בשורת הפקודה

(classpath או cp)בעזרת הדגל הגדרת תיקיות החיפוש בסביבת הפיתוח

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

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

10

jar

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

התוכניתjar )Java ARchive( אורזת מספר מחלקות לקובץ אחד תוך שמירה על מבנה החבילות הפנימי שלהן

הפורמט תואם למקובל בתוכנות דומות כגוןzip, tar, rarואחרות

-כדי להשתמש במחלקות הארוזות אין צורך לפרוס את קובץ הjar ניתן להוסיפו לCLASSPATHשל התוכנית

התוכניתjar -היא חלק מה JDK וניתן להשתמש בה משורת הפקודה או מתוך סביבת הפיתוח

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

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

11

API and javadoc -קובץ הjar עשוי שלא להכיל קובצי מקור כלל, אלא רק קובצי class

)למשל משיקולי זכויות יוצרים( איך יכיר לקוח שקיבלjar מספק תוכנה כלשהו את הפונקציות

, כדי שיוכל לעבוד איתם?jarוהמשתנים הנמצאים בתוך ה-

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

תיאור מילולי של אופן השימוש בהם

תוכנה בשםjavadoc בפורמט תיעוד אוטומטי מחוללת html על בסיס הערות התיעוד שהופיעו בגוף קובצי המקור

תיעוד זה מכונהAPI )Application Programming Interface(

תוכנת הjavadoc -היא חלק מה JDK וניתן להשתמש בה משורת הפקודה או מתוך סביבת הפיתוח

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

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

12

/** Documetntaion for the package */package somePackage;

/** Documetntaion for the class * @author your name here */public class SomeClass {

/** Documetntaion for the class variable */public static int someVariable;

/** Documetntaion 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;}

}

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

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

13

Java API

חברתSun תיעדה את כל מחלקות הספרייה של אתר javadoc וחוללה עבורן בעזרת Javaשפת

תיעוד מקיף ומלא הנמצא ברשת:

http://java.sun.com/j2se/1.5.0/docs/api/

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

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

14

תיעוד וקוד

בעזרת מחולל קוד אוטומטי הופך התיעוד לחלקבלתי נפרד מקוד התוכנית

הדבר משפר את הסיכוי ששינויים עתידיים בקודיופיעו מיידית גם בתיעוד וכך תשמר העקביות בין

השניים

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

מחלקות כטיפוסי נתונים

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

15

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

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

16

מחלקות כטיפוסי נתונים

ביסודה של גישת התכנות מונחה העצמים היא ההנחהבשפת ע"י ישויות מעולם הבעיהשניתן לייצג ישויות

התכנות

( בכתיבת מערכת תוכנה בתחום מסויםdomain נרצה ,)לתאר את המרכיבים השונים באותו תחום כטיפוסים

ומשתנים בתוכנית המחשב

:התחומים שבהם נכתבות מערכות תוכנה מגוונים בנקאות, ספורט, תרופות, מוצרי צריכה, משחקים

ומולטימדיה, פיסיקה ומדע, מנהלה, מסחר ושרותים...

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

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

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

17

מחלקות כטיפוסי נתונים

של טיפוסים הרכבהמחלקות מגדירות טיפוסים שהם אחרים )יסודיים או מחלקות בעצמם(

מופע( instance של מחלקה נקרא )עצם( object)

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

:כל מופע עשוי להכיל( נתוניםdata members, instance fields)( שרותיםinstance methods) ,בנאים( פונקציות אתחולconstructors)

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

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

18

מחלקות ועצמים

כבר ראינו בקורס שימוש בטיפוסים שאינם פרימיטיביים: מחרוזתומערך

גם ראינו שעקב שכיחות השימוש בהם יש להם הקלות תחביריות והעמסת אופרטור(newמסוימות )פטור מ-

:ראינו כי עבודה עם טיפוסים אלה מערבת שתי ישויות נפרדותהמכיל את המידעהעצם :משתנה שדרכו ניתן לגשת לעצם ההפנייה :

)זאת בשונה ממשתנים יסודיים )טיפוסים פרימיטיביים

:דוגמא: בהגדרהint i=5 , j=7;i -וj הם מופעים שלint" כשם ש hello "" -וworld הם מופעים "

Stringשל

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

שרותי מופע

פונקציות אשר מופעלות על מופע מסוים של שרותי מופע למחלקות יש –המחלקה

:תחביר של הפעלת שרות מופע הוא

objRef.methodName)arguments(

לדוגמא:

String str = "SupercaliFrajalistic";int len = str.length();

( זאת בשונה מזימון שרות מחלקהstatic:)

className.methodName)arguments(

לדוגמא:

String.valueOf(15); // returns the string “15”

!שימו של כי האופרטור נקודה ).( משמש בשני המקרים בתפקידים שונים לגמריJava בשפת 1תוכנה

אוניברסיטת תל אביב

19

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

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

20

שימוש במחלקות קיימות

לטיפוס מחלקה תכונות בסיסיות, אשר סיפק כותב המחלקה, ואולםניתן לבצע עם העצמים פעולות מורכבות יותר ע"י שימוש באותן תכונות

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

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

כותב המחלקה לא סיפק את הקוד שלה אלא רק עמוד תיעוד המתאר(class של קובצי JARאת הצב )המחלקה ארוזה ב

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

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

21

Turtle API

- – פונקצית אתחולבנאיניתן לייצר מופעים חדשים של

המחלקה ע"י קריאה לבנאי עם newהאופרטור

סוגים 2 – נפריד בין שרותיםשונים:

– אינם שרותי מחלקה1.מתייחסים לעצם מסוים,

staticמסומנים

– שרותים אשר שרותי מופע2.מתייחסים לעצם מסוים. יופנו לעצם מסוים ע"י שימוש

באופרטור הנקודה

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

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

22

Turtle API

סוגים של שרותי מופע:( – queries )שאילתות1.

שרותים שיש להם ערך מוחזר •בדרך כלל לא משנים את •

מצב העצםבשיעור הבא נדון בסוגים •

שונים של שאילתות

( – commands )פקודות2.שרותים ללא ערך מוחזר•בדרך כלל משנים את מצב •

העצם שעליו הם פועלים

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

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

23

דוגמת שימושpublic class TurleClient {

public static void main(String[] args) {Turtle leonardo = new Turtle();

if(!leonardo.isTailDown()) leonardo.tailDown();

leonardo.moveForward(50);leonardo.turnRight(90);

leonardo.moveForward(50);leonardo.turnRight(90);

leonardo.moveForward(50);leonardo.turnRight(90);

leonardo.moveForward(50);leonardo.turnRight(90);

}}

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

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

24

עוד דוגמת שימוש

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);

}}

}

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

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

25

"לאונרדו יודע..."

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

מדוע המחלקהTurtle לא הכילה מלכתחילה את ?drawSquarePattern ו- drawSquareהשרותים

יש לכך יתרונות וחסרונות

?איך לימדנו את הצב את התעלולים החדשים

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

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

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

הגדרת טיפוסים חדשים

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

26

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

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

27

The cookie cutter

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

( תבנית העוגיותcookie cutter היא מעין )ליצירת מחלקה עוגיות

עצמים( שנוצקו מאותה תבניתמופעיםהעוגיות עצמן הן(

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

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

)שוקולד? טעמןשיווצרו בעזרת התבנית אבל לא מה יהיה וניל?(

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

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

28

דוגמא

נתבונן במחלקהMyDate:לייצוג תאריכים

public class MyDate {int day;int month;int year;

} שימו לב! המשתניםday, month -ו year הוגדרו ללא המציין

static ולכן בכל מופע עתידי של עצם מהמחלקה MyDate 3 יופיעו השדות האלה

כאשר ה שאלה :JVM טוען לזיכרון את המחלקה איפה בזיכרון ?year ו- day, monthנמצאים השדות

הם עוד לא נמצאים! הם יווצרו רק כאשר לקוח ייצר מופע תשובה :)עצם( מהמחלקה

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

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

29

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

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

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

30

אם שרות, אז עד הסוף

האם התאריךd1?מייצג תאריך תקין ?מה יעשה כותב היומן כאשר יצטרך להזיז את הפגישה בשבוע

האםd1.day += 7? כמו כן, אם למחלקה כמה לקוחות שונים – אזי הלוגיקה הזו תהיה

משוכפלת אצל כל אחד מהלקוחות

אחריותו של מי לוודא את תקינות התאריכים ולממש את הלוגיקההנלווית?

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

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

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

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...}

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

31

כדי להכליל את הדוגמא נחליף המשתנה שם שמסמן dאת

date -ב this עצם שיסמל מטיפוס כלשהו

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

public class MyDate {

private int day;private int month;private int year;

public static void incrementDate(MyDate this){ // changes d to be the consequent day }

public static String toString(MyDate this){return this.day + "/" + this.month + "/" + this.year;

}

public static void setDay(MyDate this, int day){/* changes the day part of d to be day if * the resulting date is legal */

}

public static int getDay(MyDate this){return this.day;

}

private static boolean isLegal(MyDate this){// returns if d represents a legal date

}

// more...}

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

32

שימו לב! במילה הוא thisהשימוש משתנה של שם כמציין

אסור!בשפת thisהמילה שמורה מילה היא java ואסורה

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

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

זה

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

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

33

נראות פרטית מכיוון שהשדות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;

}}

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

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

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

34

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עד לביצוע השמת התאריכים הוא מייצג את התאריך הלא חוקי

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

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

35

שרותי מופע

כדי לפתור את הבעיה הראשונה, נשתמש בסוג שני של – שרותי מופעJavaשרותים הקיים ב

אלו הם שרותים המשויכים למופע מסוים – הפעלה שלהםנחשבת כבקשה או שאלה מעצם מסוים – והיא מתבצעת

בעזרת אופרטור הנקודה

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

מאחורי הקלעים הקומפיילר מייצר משתנה בשםthis ומעביר אותו לפונקציה, ממש כאילו העביר אותו המשתמש

בעצמו

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

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

36

ממתקים להמונים

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

ניתן לדמיין את שרות המופעm)( של מחלקה C כאילו היה כארגומנט: Cשרות מחלקה )סטטי( המקבל עצם מהטיפוס

public class C {

public void m(args){...

}} public static void m(C this, args) {

…}

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

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

37

ממתקים להמונים

בראייה זו, הקריאות למתודהm)( של לקוחות המחלקה C יתורגמו ע"י העברת ההפניה שעליה בוצעה הקריאה

כארגומנט לשרות הסטטי:

public class SomeClient {

public static void main(String[] args) {C obj = new C();obj.m(args);

}

} C.m(obj,args)

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

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

38

"לא מה שחשבת"

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

בהמשך הקורס נראה כי לשרותי המופע בJava תפקיד (, dynamic dispatch )בשיגור שרותים דינאמימרכזי

תכונה בשפה המאפשרת החלפת המימוש בזמן ריצה ופולימורפיזם

תאור שרותי מופע כסוכר תחבירי הוא פשטני )ושגוי!( אך לגבי פעולת השרות בשלב זה של אינטואיציה טובהנותן

הקורס

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

public class MyDate {

private int day;private int month;private int year;

public static void incrementDate(MyDate this){ // changes itself to be the consequent day }

public static String toString(MyDate this){return this.day + "/" + this.month + "/" + this.year;

}

public static void setDay(MyDate this, int day){/* changes the day part of itself to be day if * the resulting date is legal */

}

public static int getDay(MyDate this){return this.day;

}

private static boolean isLegal(MyDate this){// returns if the argument represents a legal date

}

// more...}

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

39

הקוד הזה חוקי !

מוכר בתוך thisהמשתנה שרותי המופע כאילו הועבר

ע"י המשתמש.

אולם לא חובה להשתמש בו

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

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...}

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

40

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

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

41

בנאים

כדי לפתור את הבעיה שהעצם אינו מכיל ערך תקין מיד עםבנאייצירתו נגדיר עבור המחלקה

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

וחתימתה אינה כוללת ערך שהיא מאתחלת המחלקה מוחזר

-זיכרון המוקצה על הHeap למשל ע"י( new מאותחל )(, null,false,0אוטומטית לפי הטיפוס שהוא מאכסן )

כך שאין צורך לציין בבנאי אתחול שדות לערכים אלה

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

וממופה למצב מופשט בעל משמעות )יוסבר בהמשך(

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

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());}

}

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

42

MyDateהגדרת בנאי ל

MyDateקוד לקוח המשתמש ב-

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

Default constructor is created only if there are no

constructors.

If you define any constructor for your class, no default constructor

is automatically created.

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

43

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

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

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

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

45

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

בדוגמא הבאה נראה כיצד מייצר הקומפיילר עבור כל בנאי וכל שרות thisעבורנו את ההפניה

מופע

נתבונן במחלקהPoint המייצגת נקודה במישור הדו מימדי. כמו כן המחלקה מנהלת מעקב בעזרת

משתנה גלובלי )סטטי( אחר מספר העצמים שנוצרו מהמחלקה

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

3 שדות מופע ו-2נסתפק בבנאי, שדה מחלקה, שרותי מופע

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

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

46

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;

}

/** tolerant method, no precondition - for nonresponsible clients * @post (newX > 0.0 && newX < 100.0) $implies getX() == newX * @post !(newX > 0.0 && newX < 100.0) $implies getX() == $prev(getX()) */public void setX(double newX) {

if(newX > 0.0 && newX < 100.0) doSetX(newX);

}

/** only business logic. Has a preconditon - for responsible clients * @pre (newX > 0.0 && newX < 100.0) * @post getX() == newX */public void doSetX(double newX) {

x = newX;}

// More methods...}

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

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

47

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());}

}

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

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

48

Javaמודל הזיכרון של

משתנים מקומיים וארגומנטים – כל מתודה משתמשת באזור מסוים

של המחסנית

משתנים גלובלים ועצמים – אינו תלוי במתודה

הנוכחית שרצה

קוד התוכנית

CODE

HEAPSTACK

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

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

49

"בנץ הוא זה"

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());

}

}

CODE

HEAP

mainargs

p1

Point)x,y(

[ ][ ]

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; }

Point.numOfPoints

0

0

x 1.0

2.0y

this

STACK

x0y

1.0

2.0

1

(target )עצם מטרהבכל הפעלה של שרות מופע או בנאי יש מצביעה לעצם זה thisשעליו הופעל השרות. ההפניה

מצביעה thisבמהלך ריצת בנאי, ההפניה על העצם שזה עתה הוקצה

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

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

50

"בנץ הוא זה"

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());

}

}

CODE

HEAP

mainargs

p1

Point)x,y(

[ ][ ]

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; }

Point.numOfPoints

1

p2

x 10.0

20.0y

this

STACK

x

y

1.0

2.0

20x0y

10.0

20.0

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

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

51

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());

}

}

CODE

HEAP

mainargs

p1

setX

[ ][ ]

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; }

Point.numOfPoints

2

p2

newX 11.0

this

x

y

1.0

2.0

11.0

x

y

10.0

20.0

newX 11.0

this )newX(this.doSetX היא בעצם )doSetX)newXהקריאה איזה עצם הוא מטרת הקריאה?

this.doSetX(newX);

STACK

doSetX

הוא העצם עצם המטרהבזימון של שרות מופע תצביע לעצם זה thisשעליו הופעל השרות. ההפניה

this.x = newX היא בעצם x = newXההשמה

{ this.x = newX; }

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

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

52

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());

}

}

CODE

HEAP

mainargs

p1

setX

[ ][ ]

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; }

Point.numOfPoints

2

p2

newX 21.0

this

x

y

11.0

2.0

21.0x

y

10.0

20.0

newX 21.0

this סוכר תחבירי היא )doSetX)newXהקריאה איזה עצם הוא מטרת הקריאה?)this.doSetX)newXשל

this.doSetX(newX);

STACK

doSetX

הוא העצם עצם המטרהבזימון של שרות מופע תצביע לעצם זה thisשעליו הופעל השרות. ההפניה

this.x = newX של סוכר תחבירי היא x = newXההשמה

{ this.x = newX; }

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

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

53

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());

}

}

CODE

HEAP

mainargs

p1

getX

[ ][ ]

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; }

Point.numOfPoints

2

p2

this

x

y

11.0

2.0

21.0x

y 20.0

"return this.x" הוא בעצם "return x"המשפט איזה עצם הוא מטרת הקריאה?

STACK

{ this.x = newX; }

{ return this.x; }

“p1.x == ”“p1.x == ”

“11”“11”

“p1.x == 11”“p1.x == 11”

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

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

54

סיכום ביניים

שרותי מופע( instance methods בשונה משרותי מחלקה )(static method( פועלים על עצם מסוים )this)

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

משתני מופע( instance fields בשונה ממשתני מחלקה )(static fields הם )הם נוצרים רק שדות בתוך עצמים .

( newכאשר נוצר עצם חדש מהמחלקה )ע"י בעוד ששדות מחלקה הם משתנים גלובלים. קיים עותק אחד

שלהם, שנוצר בעת טעינת קוד המחלקה לזכרון, ללא קשר ליצירת עצמים מאותה המחלקה