1 / 27

המשך תכנות מונחה עצמים

המשך תכנות מונחה עצמים. תרגול מס' 9. היום בתרגול. this Shallow Copy, Deep Copy שיטות מיוחדות חריגות ( Exceptions ). תזכורת: מחלקות ואובייקטים. הנה המחלקה MyString :. public class MyString { //class fields private char [] elements ; private int length ; //class method

jabrams
Download Presentation

המשך תכנות מונחה עצמים

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. המשך תכנות מונחה עצמים תרגול מס' 9

  2. היום בתרגול • this • Shallow Copy, Deep Copy • שיטות מיוחדות • חריגות (Exceptions)

  3. תזכורת: מחלקות ואובייקטים • הנה המחלקה MyString: publicclass MyString { //class fields private char[] elements; private intlength; //class method publicint length(){ returnlength; } } שדות – מייצגים מצב של האובייקט שיטה – מתארת התנהגות של האובייקט

  4. תזכורת: מחלקות ואובייקטים • על מנת ליצור אובייקט מסוג MyString, נשתמש במילה new: • אך כיצד ניתן לשים ערכים בתוך המחרוזת שלנו? • לשם כך נגדיר בנאי, שבעזרתו נאתחל את שדה האובייקט MyString s = new MyString();

  5. תזכורת: בנאי (constructor) • בנאי – שיטה מיוחדת עבור מחלקה שתפקידה לייצר אובייקט ולאתחל את שדותיו publicclass MyString { //class fields private char[] elements; private intlength; //constructor with a parameter public MyString(char[] otherElements){ length = otherElements.length; elements = newchar[length]; for (int i = 0; i < otherElements.length; i++) { elements[i] = otherElements[i]; } } ... } השם זהה לשם המחלקה ואין ערך החזרה

  6. this • ראינו כי ניתן להגדיר מספר בנאים למחלקה בעזרת העמסה (Overloading) • ניתן לקרוא מבנאי אחד לבנאי אחר בעזרת המילה השמורה: • לדוגמה: • הקריאה חייבת להתבצע בשורה הראשונהשל הבנאי this public MyString(MyString other){ this(other.elements); } מה היתרון בשימוש בדרך זו? ( )

  7. this • דוגמה נוספת: מה עושה הבנאי השני? publicclass MyString{ privatechar[] elements; privateint length; public MyString(String s) { … } public MyString() { this(""); … } }

  8. this • ניתן להשתמש ב - this על מנת להבדיל בין שדה לבין פרמטר או משתנה לוקאלי בעלי אותו שם. לדוגמה: בעזרת האופרטור (.) publicclass MyString{ private char[] elements; private intlength; public MyString(char[] elements, int length) { this.length = length; this.elements = newchar[this.length]; for (int i = 0; i < this.length; i=i+1) this.elements[i] = elements[i]; } }

  9. תזכורת • תזכורת (מההרצאות) – המחלקות Point ו- Circle: publicclass Point { public doublex; public doubley; public Point() { x = 0; y = 0; } public Point(Point p) { x = p.x; y = p.y; } } בנאי חסר פרמטרים בנאי מעתיק

  10. תזכורת publicclass Circle{ public Point center; public double radius; //constructors public Circle() { center = new Point(); radius = 0; } public Circle(Point cen, double rad) { center = new Point(cen); if (rad >= 0) radius = rad; else rad = 0; } … }//Circle בנאי חסר פרמטרים בנאי המקבל את כל השדות

  11. Deep Copy ו- Shallow Copy • בנאי מעתיק אפשרי ל- Circle: • מה יקרה אם נבצע את הפעולות הבאות: • הבנאי המעתיק משתמש בגישת ה- Shallow Copy. public Circle(Circle other) { center = other.center; radius = other.radius; } Copy constructor publicstaticvoid main(String[] args){ Circle circ1 = new Circle(); Circle circ2 = new Circle(circ1); circ2.center.x = 4; }

  12. Deep Copy ו- Shallow Copy • בנאי מעתיק אפשרי ל- Circle: • מה יקרה עכשיו אם נבצע את הפעולות הבאות: • הבנאי המעתיק משתמש בגישת ה- Deep Copy. public Circle(Circle other) { center = new Point(other.center); radius = other.radius; } publicstaticvoid main(String[] args){ Circle circ1 = new Circle(); Circle circ2 = new Circle(circ1); circ2.center.x = 4; }

  13. המחלקה Object במחלקה Object מוגדרים מימושי ברירת המחדל לשיטות המשותפות לכל האובייקטים. למשל ... publicStringtoString() כאשר ממשנו שיטה זו במחלקות שייצרנו ביצענו דריסה לשיטת ברירת המחדל שירשנו מהמחלקה Object. שיטה משותפת נוספת הינה publicbooleanequals(Object obj) אשר מבצעת השוואה לוגית בין שני אובייקטים (כמו שראינו ב- String). שימו לב כי שוויון לוגי אינו בהכרח השוואה של כל שדות האובייקט.

  14. שיטות משותפות לכל האובייקטים: toString • עד עתה כשרצינו להדפיס ערך כלשהו השתמשנו בפונקציה מהמשפחה של System.out.print • כיצד נוכל להדפיס אובייקט מסוג Complex? • ב- Java לכל אובייקט יש שיטה בשם toString, המחזירה String כמו שהמתכנת של המחלקה מחליט publicclass Point{ publicdoublex; publicdoubley; public String toString() { return"(" + x + " , " + y + ")"; } }

  15. שיטות משותפות לכל האובייקטים: toString • כעת, כשנדפיס אובייקט מסוג Point (באופן הבא): • שימו לב כי ניתן היה (אך לא חובה) לקרוא לשיטה כך: • במקרה השני, הפונקציה println מפעילה את שיטת ה toString של האובייקט Point p1 = new Point(5, 7); System.out.println(p1.toString()); (5.0 , 7.0) Point p1 = new Point(5, 7); System.out.println(p1);

  16. השיטה equals • נרצה לממש את השיטה equals עבור Point : • מה יקרה כאשר other הוא null ? שגיאה בזמן ריצה: NullPointerException publicclass Point { publicdoublex; publicdoubley; // ... public boolean equals(Object other) { boolean ans; Point otherPoint = (Point)other; ans = (x==otherPoint.x) && (y==otherPoint.y); return ans; } }

  17. השיטה equals • נרצה לממש את השיטה equals עבור Point : • מה יקרה כאשר other הוא אינו מטיפוס Point ? שגיאה בזמן ריצה: ClassCastException publicclass Point { publicdoublex; publicdoubley; // ... public boolean equals(Object other) { boolean ans; Point otherPoint = (Point)other; ans = (x==otherPoint.x) && (y==otherPoint.y); return ans; } }

  18. השיטה equals • נרצה לממש את השיטה equals עבור Point : publicclass Point { publicdoublex; publicdoubley; // ... public boolean equals(Object other) { boolean ans = false; if(other instanceof Point) { Point otherPoint = (Point)other; ans = (x==otherPoint.x) && (y==otherPoint.y); } return ans; } } מחזיר true רק כאשר other אינו null ומטיפוס Point

  19. equals השיטה • אם לא היינו מממשים את (מבצעים דריסה של) השיטה equals במחלקה Point, בעת הקריאה לשיטה equals היינו פונים לשיטה equals הממומשת ב-Object אשר משווה כתובות. publicboolean equals(Object other){ return this == other; } השוואה בין כתובות (הערך בטבלת המשתנים)

  20. equals השיטה • אם לא היינו מממשים את (מבצעים דריסה של) השיטה equals במחלקה Point, בעת הקריאה לשיטה equals היינו פונים לשיטה equals הממומשת ב-Object אשר משווה כתובות. publicboolean equals(Object other){ return this == other; } ??מה יקרה אם נגדיר עבור מחלקה Point את השיטה הבאה: ?? publicbooleanequals(Point other) !! לא ביצענו דריסה של השיטה equals של מחלקת האב Object, מאחר והחתימה שונה.

  21. חריגות (Exceptions) חריגה היא אירוע המתרחש במהלך תוכנית המפר את תהליך הריצה הנורמאלי של פקודות התוכנית. לעיתים חריגות מתרחשות בגלל תקלות בלתי צפויות, כגון בעיה בקובץ אליו כותבים (למשל אין הרשאות כתיבה), ולעיתים בגלל תקלות תוכנה, כגון שליחת פרמטר לא מתאים לפונקציה.

  22. כבר נתקלנו ב-RuntimeExceptions וראינו כי ניתן לזרוק RuntimeException באמצעות throw ArithmeticException: ניסיון חלוקה באפס IndexOutOfBoundsException: חריגה ממערך NullPointerException: ניסיון לפעול על משתנה שאינו פרימיטיבי בעל ערך null

  23. Throw RuntimeException publicclass Car { privatefinalint MAX_SPEED = 210; privatefinalint MIN_SPEED = -20; privateint speed; … publicvoidsetSpeed(int speed){ if ((speed >= MIN_SPEED) && (speed <= MAX_SPEED)) this.speed = speed; else thrownewRuntimeException(“Illegal speed”); } } publicstaticvoid main(String[] args) { Car car = new Car(); car.setSpeed(300); } Output: Exception in thread "main" java.lang.RuntimeException: Illegal Speed at Car.setSpeed(Car.java:11) at Car.main(Car.java:17)

  24. סוגי Exceptions Object Exception IOException RuntimeException NullPointerException

  25. Exception • ניתן לייצר חריגהע"י פקודת throwהמייצרת את אירוע החריגה. • ישנן שתי דרכים לטפל בחריגה: • לתפוס את ה- Exception על ידי שימוש במילים השמורות tryו-catch • להעביר את ה- Exception הלאה על ידי שימוש במילה השמורה throwsבכותרת הפונקציה שאנו כותבים. (טיפול בחריגות לא הכרחי עבור (RuntimeExceptions

  26. Throw and Catch Exceptions publicclass Car { privatefinalint MAX_SPEED = 210; privatefinalint MIN_SPEED = -20; privateint speed; … publicvoidsetSpeed(int speed) throws Exception { if ((speed >= MIN_SPEED) && (speed <= MAX_SPEED)) this.speed = speed; else thrownew Exception(“Illegal speed”); } } publicstaticvoid main(String[] args) { Car car = new Car(); car.setSpeed(100); } Compilation Error

  27. Throw and Catch Exceptions publicclass Car { privatefinalint MAX_SPEED = 210; privatefinalint MIN_SPEED = -20; privateint speed; … publicvoidsetSpeed(int speed) throws Exception { if ((speed >= MIN_SPEED) && (speed <= MAX_SPEED)) this.speed = speed; else thrownew Exception(“Illegal speed”); } } publicstaticvoid main(String[] args) { Car car = new Car(); try{ car.setSpeed(300); System.out.println("Broke the speed limit !"); } catch(Exception e){ System.err.println("Caught Exception: "+e.getMessage()); } System.out.println("Current speed is "+car.getSpeed()+” km/h); } Output: Caught Exception: Illegal Speed Current speed is 0 km/h

More Related