1 / 54

פיתוח מונחה עצמים – שפת JAVA

פיתוח מונחה עצמים – שפת JAVA. מבוא. References. קורס "שיטות בהנדסת תוכנה", הפקולטה למדעי המחשב, הטכניון. קורס "מערכות מידע מבוזרות", הפקולטה להנדסת תעשייה וניהול, הטכניון. מהי Java ?. המטרה המקורית לפיתוח שפת Java הייתה ליצור סביבה אחידה להרצת תכניות על מכשירים "חכמים".

thanh
Download Presentation

פיתוח מונחה עצמים – שפת JAVA

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. פיתוח מונחה עצמים – שפת JAVA מבוא

  2. References • קורס "שיטות בהנדסת תוכנה", הפקולטה למדעי המחשב, הטכניון. • קורס "מערכות מידע מבוזרות", הפקולטה להנדסת תעשייה וניהול, הטכניון.

  3. מהי Java? • המטרה המקורית לפיתוח שפת Java הייתה ליצור סביבה אחידה להרצת תכניות על מכשירים "חכמים". • כל מכשיר היום נעשה חכם יותר ויותר ולמעשה מכיל סוג של מחשב בתוכו: וידאו שניתן לתכנת, מיקרוגל, פלאפון. • הבעיה:בכל מכשיר של כל יצרן צורת התכנות שונה ובדרך כלל לא ניתן להטעין עדכון לתוכנה שתוסיף למכשיר פונקציונאליות. • כיצד בונים סביבה כך שניתן יהיה להריץ תכניות על סוגים כל כך רבים של מעבדים שונים ומשונים?

  4. הפתרון של Java: הגדרת מחשב דמיוני The Java Virtual Machine. כל תכניות Javaנכתבות רק עבור מחשב זה ורק עליו הן צריכות לרוץ. • שפת המכונה של מחשב זה נקראת Java Byte-Code. • עבור כל מכשיר שעליו רוצים להריץ תכניות Java יש לכתוב סימולטור ל- Java Virtual Machine המחקה את פעולתו. ואז, כל תכניות ה Java שקיימות ירוצו עליו. • הדבר דומה לסימולטורים המאפשרים להריץ תכניות PC על Mac או על Unix. • סימולטור JVM (שלהבא נקרא לו פשוט JVM) מסוגל להריץ כל תכנית שכתובה ב Java Byte-Code.

  5. file1.c file1.o gcc –c file1.c a.out gcc *.o file2.c file2.o gcc -c file2.c file3.c file3.o gcc -c file3.c קבצי מקור– שפתC C compiler קבציobject –שפת מכונה linker קובץexecutable –שפת מכונה צורת עבודה באופן כללי, צורת העבודה בתכנית C++/C היא כזו:

  6. Class1.java Class1.class java Class1 javac Class1.java Class2.java Class2.class javac Class2.java Class3.java Class3.class javac Class3.java קבצי מקור – שפתJava Java compiler קבציbytecode JVM simulator צורת עבודה לעומת זאת צורת העבודה ב Java היא כזו:

  7. Naming Conventions • שמות מתודות, משתנים, ואובייקטים צריכים להתחיל באות קטנה next, push(), index, etc. • שמות המחלקות חייבים להתחיל באות גדולה String, StringBuffer, Vector, Calculator, etc. • שמות קבועים צריכים להכיל רק אותיות גדולות DEBUG, MAX_SCROLL_X, CAPACITY. final double PI = 3.1415926; • הפרדה בין מילים בתוך שמות מחלקה נעשית ע"י אותיות גדולות. • הפרדה בין מילים בתוך שמות קבועים נעשית י"י קו-תחתון (underscore).

  8. התכנית הראשונה שלנו ב- Java התכנית הראשונה שלנו ב Java תהיה תכנית המדפיסה HelloWorld על המסך: public class HelloWorld { public static void main (String[] args) { System.out.println("Hello World"); } } את התכנית הזו נכתוב בקובץ בשם “HelloWorld.java” . שימו לב: שם הקובץ חייב להיות זהה לשם המחלקה.

  9. כלים שאנו מקבלים עם java • javac- קומפיילר מ- java ל byte-code . השימוש בו הוא javac Classname.java ומתקבל הקובץ Classname.class. ניתן לקמפל בבת-אחת מספר קבצים ע"י javac Classname1.java Classname2.java או javac *.java • java - סימולטור ל JVM (Java Virtual Machine). השימוש בו הוא java Classname כאשר Classname.class הוא קובץ .class (כלומר byte-code) שמכיל את הפונקציה public static void main(String args[] ).

  10. Access control בקרת גישה • publicmember (function/data) • Can be called/modified from outside. • protected • Can be called/modified from derived classes. • private • Can be called/modified only from the current class. • default (if no access modifier stated ) • Usually referred to as “Friendly”. • Can called/modified/instantiated from the same package.

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

  12. הגדרת מחלקה נגדיר מחלקה בשם Line המתארת קו. לקו מספר תכונות: נקודת התחלה, נקודת סיום, עובי וצבע. כמו כן לקו פונקציה בשם draw() המשמשת לציור הקו על המסך. שימו לב: אנחנו מגדירים גם מחלקת- עזר בשם Point • public class Point • { private int x, y; • public Point() { x=y=0; } • public Point (int x_, int y_) { x = x_; y = y_; } • public void setX(int x_) • { x = x_; } • public void setY(int y_) • { y = y_; } • public int getX() • { return x; } • public int getY() • { return y; } • } כתיבת שתי פונקציות בעלות אותו שם נקרא העמסה (overloading)

  13. אתחול עצמים Constructor ב Java קיים מנגנון מובנה לאתחל עצמים constructor. Constructor הוא פונקצית מחלקה מיוחדת הנקראת בזמן יצירת עצם חדש ממחלקה. • לדוגמא עבור המחלקה Point: • public Point (int x_, int y_) { x = x_; y = y_; } פונקצית ה- constructor מוגדרת בשם המחלקה והיא מקבלת פרמטרים לאתחול העצם.

  14. נגדיר מחלקה בשם Line המתארת קו. לקו מספר תכונות: נקודת התחלה, נקודת סיום, עובי וצבע. כמו כן לקו פונקציה בשם draw() המשמשת לציור הקו על המסך. • public class Line • { private Point s; // start point • private Point t; // end point • private width; • private color; • public Line() { s = new Point(); • t = new Point(); • width=color=0; } • public Line (int x1, int y1, int x2, int y2) • { s = new (x1,y1); • t = new (x2,y2); } • public void draw() • { // draw line • } public void setColor(int c) { color = c;} public int getColor() { return color;} public void setWidth(int w) { width = w;} public int getWidth () { return width; } }

  15. הגדרת עצם נכתוב פונקציה main במחלקה שתגדיר ותשתמש בעצמים מסוג Line. • public class LineApp • { • public static void main (String[] args) • { • Line line1 = new Line(); • Line line2; • line1.draw(); • line2 = new(22,12,48,100); • line2.setColor(4); • line2.setWidth(2); • line2.draw(); • } • }

  16. שימוש במחלקות ספריה לצורך הדוגמא הגדרנו מחלקה Point אבל בספריה הגרפית של Java קיימת מחלקה Point. כדי להשתמש במחלקה זו יש צורך לייבא (import) את הספריה המתאימה בתחילת התוכנית: import java.awt.Point; ניתן לייבא את כל המחלקות שבספריית awt באופן מקוצר: import java.awt.*; ההוראה import מקבילה להוראה #include שב C/C++ .

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

  18. הגדרת עצם ממחלקה ראשית • הפתרון: פונקציה main של מחלקה ראשית היא סטטית, ולכן ניתן להגדיר בה עצמים מהמחלקה עצמה. • public class Point • { • … • Public static void main (String[] args) • { • Point p1; • … • } • } • פונקציה סטטית אינה נקראת בהקשר לעצם, אלא בהקשר למחלקה, ולכן אין צורך בעצם קיים כדי לקרוא לה. • זו הסיבה שהפונקציה main הנקראת ע"י מערכת כנקודת התחלה של יישום חייבת להיות מוגדרת כסטטית: מפונקציה זו מתחילים להגדיר עצמים.

  19. טיפוסים • ב Java קיימים מספר טיפוסים בסיסיים הדומים בשמם ובאופן הגדרתם לאלו שב C++.

  20. מחרוזת String • ב Java קיימת מחלקה תקנית לייצוג מחרוזות בשם String. • המחלקה כוללת מגוון פעולות על מחרוזות כגון העתקה, שרשור, הצבה, הדפסה. • דוגמה לשימוש ב String public class StrApp{ public static void main (String[] args) { String s1 = “Hello”; String s2 = new String(“Israel”); System.out.println(s1+s2); // prints Hello Israel ; s1, s2 not changed System.out.println(s1.concat(s2); // prints Hello Israel ; s1changed } • עבור עצמים מטיפוס String ניתן להשתמש בפעולות: ==, =!, >, < + (משמעות-שרשור) http://java.sun.com/j2se/1.4.2/docs/api/

  21. מערכים Arrays מערך הוא מחלקה. בדומה ל- ++C למערך גודל קבוע. Public class Animal { … } Animal[] arr; // nothing yet … arr = new Animal[4]; // only array of pointers for(int i=0 ; i < arr.length ; i++) { arr[i] = new Animal(); // now we have a complete array

  22. השואות • אופרטור == מחזיר אמת אמ"מ לשני האופרנדים יש ערך זהה. • עובד כהלכה עבור טיפוסים פרימיטיביים. • עבור טיפוסים מורכבים משווא רק ערכי reference variables ולא תוכן של שדות. • Integer i1 = new Integer("3"); • Integer i2 = new Integer("3"); • Integer i3 = i2; • i1 == i1 && i1 != i2 && i2 == i3 This expression evaluates to true

  23. כדי להשוות בין שני אובייקטים מטיפוס מורכב משתמשים בפונקציה: • boolean equals ( Object o) • מימוש פונקציה בברירת מחדל משתמש באופרטור ==. • רוב מחלקות מ- API מספקות מתודה ייחודית להם. • ניתן להעמיס (override) מתודה זו על מנת לספק מימוש ייחודי הדרוש This expression evaluates to true • i1.equals(i1) && i1.equals(i2)

  24. העמסה של המתודה equals public class Name { String firstName; String lastName; ... public boolean equals(Object o) { if (!(o instanceof Name)) return false; Name n = (Name)o; return firstName.equals(n.firstName) && lastName.equals(lastName); } }

  25. ירושה • ירושה היא מנגנון המאפשר להגדיר את המשותף שבין מספר המחלקות במחלקה אחת. • המחלקה בה מוגדר חלק המשותף נקראת מחלקת בסיס (Basic class). • מחלקה יורשת ממחלקת בסיס נקראת מחלקה נגזרת(Derived class). • ירושה יוצרת יחס “is a” : • המילה שמורה extendsמציינת ירושה. public class A { …} כדי לציין שמחלקה B יורשת מ A נכתוב public class B extends A { … } בניגוד ל ++C ב Java ניתן לרשת רק ממחלקה אחד. יתרון: מניע בעיות ובאגים; חסרון: שכתוב קוד.

  26. Base Derived ירושה • כללים של ירושה: • המחלקה הנגזרת יורשת את כל התכונות והפונקציות ממחלקת הבסיס. • המחלקה הנגזרת יכולה להגדיר תכונות ופונקציות חדשות. • המחלקה הנגזרת יכולה לדרוס (override) פונקציות שירשה. סימון: שימו לב: למרות שלא ציינו זאת במפורש, ל- Line יש מחלקת בסיס – כלומר מחלקה ש- Line יורשת ממנה. מחלקת בסיס זו נקראת Object . כל המחלקות ב Java יורשות מ- Object.

  27. דוגמות לירושה – היררכית עובד-מנהל • שאלה: איזה מחלקה ניתן להוסיף בהיררכיה זו כמחלקת בסיס?

  28. המחלקה "עובד" public class Worker { String name; int id; float salary; ... public Worker( String n, int i, float s) { name = n; id = i; salary = s; } public void print() { System.out.println(name); System.out.println(id); System.out.println(salary); } }

  29. המחלקה "מנהל" public class Manager extends Worker{ Worker[] workerList; ... public Manager( String n, int i, float s, Worker[] wl) { super(n,I,s); workerList = wl; } public void print() { super.print(); for (int I=0; I<workerList.length); I++) workerList[I].print(); System.out.println(); } } כיוון שבמחלקת הבסיס הוגדר כבר constructor, אנו מפעילים אותו ע"י שימוש במילה שמורה super.

  30. המחלקה "נשיא" public class President extends Manager { Manager[] managerList; ... public Manager( String n, int i, float s, Worker[] wl, Manager[] ml) { super(n,i,s,wl); managerList = ml; } public void print() { super.print(); for (int I=0; I< managerList.length); I++) managerList[I].print(); System.out.println(); } }

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

  32. פולימורפיזם Polymorphism • פולימורפיזם הוא יכולת להתייחס לעצמים מטיפוסים שונים באופן אחיד. מקור השם פולימורפיזם הוא מלטינית: פולי = הרבה, מורפיה = צורה. • נניח כי היינו רוצים להחזיק את כלל עובדי הארגון במערך אחד. Worker all = new Worker[100]; • שאלות: • האם ניתן להכניס למערך כללי עצמים ממחלקות הנגזרות מ Worker? • all[3] = new Manager(“M1”,101,30000,marketing); • all[4] = new President(“P1”,1001,100000,office,managers); • 2. אם כן איזו גרסת פונקציה print() תקרא כשנקרא לה בהקשר של עצמים במערך? • all[4].print();

  33. תשובות לשתי שאלות קשורות בשני עקרונות של הפולימורפיזם: • עיקרון 1 - reference בירושה: reference למחלקת בסיס יכול בפועל להצביע על עצם ממחלקה נגזרת. תכונה זו נקראת down casting. • עיקרון 2 - פונקציות וירטואליות: כל פונקציה ב- Java מוגדרת כוירטואלית, לכן גרסת הפונקציה נקראת בהתאם לטיפול העצם. אם העצם הוא מסוג Worker תקרא פונקציה Worker.print() אם העצם הוא מסוג Manager תקרא פונקציה Manager.print() אם העצם הוא מסוג President תקרא פונקציה President.print()

  34. עיקרון 1 - הרחבה reference למחלקת בסיס יכול בפועל להצביע על עצם ממחלקה נגזרת. יש לשים לב שההפך אינו נכון: Reference למחלקה נגזרת לא יכול להצביע על עצם ממחלקת בסיס. עברת פרמטרים לפונקציות void f1 (Worker w) void f2 (Manager m) { { w.salary += 100; m.salary += 1000; } } Worker w = new Worker(…); Manager m = new Manager(…); f1(m); // OK f2(w); // Error!

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

  36. מניעת ירושה ומניעת דריסה ניתן להגדיר מחלקה כעלה בעץ הירושה, כלומר מחלקה שלא ניתן לרשת ממנה. מבצעים זאת ע"י שימוש במילה שמורה final. final class X //cannot be a base class { … } כמו כן ניתן להגדיר פונקציה כלא ניתנת לדריסה ע" ציונה כ final. class Y { final void f()// cannot override f() in subclasses { … } }

  37. Af() B f() C f() B f() C f() D D ירושה מרובה

  38. final class Base { final int i=5; final void foo() { i=10; //what will the compiler say about this? } } class Derived extends Base { // Error // another foo ... void foo() { } } • final member dataConstant member • finalmember functionThe method can’t be overridden • final class‘Base’ is final, thus it can’t be extended (String class is final)

  39. ממשקים interfaces • ממשק היא מחלקה מופשטת שכל הפונקציות שלה מוגדרות כמופשטות. • מחלקת ממשק מוגדרת ע"י המילה השמורה interface במקום class. • פונקציה מופשטת זוהי בעצם הכרזה על פונקציה ללא מימוש. • משתמשים ב interface לקביעת ממשק עבור מחלקות בעץ ירושה מסוים. • למשל: interface Collection כל מחלקה של מבנה נתונים המיישמת ממשק זה תממש את המתודות המוגדרות בו. http://java.sun.com/j2se/1.4.2/docs/api/

  40. הגדרת ממשק interface MyInterface { // static final variables // functions } תכונות הממשק מוגדרות static final גם אם המתכנתים לא ציינו זאת במפורש הגדרת מחלקה המממשת ממשק class MyClass implements MyInterface { // implement functions // give value to static variables } • ממשק יכול לרשת ממשק אחר ע"י implements. במקרה זה המחלקה המממשת אותו חייבת לממש את כל הפונקציות שירש. • מחלקה יכולה לרשת אך ורק ממחלקה יחידה, אך היא יכולה לממש מספר ממשקים. (נסו להסביר מדוע?)

  41. When to use an interface ? Perfect tool for encapsulating the classes inner structure. Only the interface will be exposed.

  42. Abstract • abstract member function, means that the function does not have an implementation. • abstract class is a class that can not be instantiated. AbstractTest.java:6: class AbstractTest is an abstract class. It can't be instantiated. new AbstractTest(); ^ 1 error NOTE: An abstract class is not required to have an abstract method in it. But any class that has an abstract method in it or that does not provide an implementation for any abstract methods declared in its superclasses must be declared as an abstract class. Example

  43. Abstract - Example package java.lang; public abstract class Shape { public abstract void draw(); public void move(int x, int y) { setColor(BackGroundColor); draw(); setCenter(x,y); setColor(ForeGroundColor); draw(); } } package java.lang; public class Circle extends Shape { public void draw() { // draw the circle ... } }

  44. חריגות Exceptions • ב Java דומה ל ++C, קיים מנגנון זריקת ותפיסת חריגות לטיפול בשגיאות ובחריגות בזמן הריצה. • דוגמאות לשגיאות בזמן הריצה: • כשלון פעולת זיכרון (חריגה בזיכרון, כשלון בהקצאת זיכרון) • כשלון פעולת קלט/פלט (קלט לא תקין, כשלון בפתיחת קובץ) • שגיאות מתמטיות (חלוקה ב 0) • ועוד.

  45. שיטות הקיימות לטיפול בשגיאות • כאשר מתגלית שגיאה/חריגה בתכנית בפונקציה מסוימת (הנקראת) ניתן לטפל בה בשיטות הבאות: • סיום התוכנית – זוהי תגובה קיצונית מידי בדר"כ. • החזרת ערך שגיאה – לא תמיד קיים ערך כזה. לדוגמא, constructor לא מחזיר ערך. כמו כן סגנון זה מחייב בדיקה בכל קריאה לפונקציה. • סימון שגיאה ע"י דגל גלובלי – נדרשת בדיקה עקבית של דגל, אחרת הוא נדרס. שיטה זו אינה תומכת בתכנות מקבילי. • קריאה לפונקציה ייעודית לטיפול בשגיאה – לא פותרת את הבעיה המקורית: פונקציה היעודית, כמו הפונקציה הנקראת, נדרשת להחליט על תגובה לשגיאה במקום לעביר את ההחלטה לפונקציה הקוראת. מנגנון זריקת ותפיסת חריגות פותר את הבעייה.

  46. מנגנון זריקת ותפיסת חריגות • מנגנון חריגות פועל כך: • פונקציה (הנקראת) הנתקלת בחריגה "זורקת" (throw)עצם חריגה. • פונקציה הקוראת המעוניינת לטפל בחריגה "תופסת" (catch) את עצם החריגה. • בפונקציה הקוראת, הקטע המיועד לטיפול בחריגות נכתב בתוך בלוק "ניסיון" (try). בלוק finally: קטע מוגדר כ finally לאחר בלוקי ה try- והcatch- יבוצע תמיד – בין אם נזרקת חריגה ובין אם לא.

  47. import java.lang.* public class SymbolTable { Symbol symbol_arr[]; int curr; public SymbolTable (int size) { curr = 0; symbol_arr = new Symbol[size]; } public void add(String name, int val)throws Exception { if (curr< symbol_arr.length) { symbol_arr[curr] = new Symbol(name,val); curr++; } else { trow new Exception(“tried to add a to a full arrat”); } } לדוגמה נממש מחלקה המייצגת טבלת סמלים. המחלקה מגדירה מערך סמלים ואינדקס המציין את מספר הסמלים הקיימים.

  48. public static void main(String args[]) { SymbolTable table = new SymbolTable(100); try{ table.add(“v1”,45); table.add(“v2”,-15); table.add(“v3”,1003); … } catch(Exception e){ System.out.println(e.getMessage()); System.exit(1); } }

  49. עיקרון "הכרז או טפל" (Declare or Handle) • ב- Javaלא ניתן להתעלם מקוד זורק חריגה. לדוגמא אם פונקציה f1() קוראת לפונקציה f2(), וזו האחרונה מכריזה על אפשרות זריקת חריגה מסוג 1E, אזי f1() חייבת לבצע אחת מהשניים: • הכרזה על זריקת חריגה E1 – ע"י throws בכותרת הפונקציה; • טיפול בחריגה 1E(Handle) – ע"י בלוקי try ו catch מתאימים. 1. void f2() throws E1 { … } Void f1() throws E1 { f2(); } 2. void f2() throws E1 {… } void f1() { try{ f2(); } catch(E1 e) { // handle exp } }

More Related