35
ססססס סס'9 1

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

  • Upload
    kendis

  • View
    57

  • Download
    3

Embed Size (px)

DESCRIPTION

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

Citation preview

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

9תרגול מס'

1

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

thisShallow Copy, Deep Copyממשקים( חריגותExceptions)

2

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

הנה המחלקהMyString:שדות –

מייצגים מצב של האובייקט

שיטה – מתארת

התנהגות של האובייקט

3

public class MyString {//class fieldsprivate char[] elements;private int length;

//class methodpublic int length(){

return length;}

}

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

על מנת ליצור אובייקט מסוגMyString נשתמש ,:newבמילה

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

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

MyString s = new MyString();

4

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

public class MyString {//class fieldsprivate char[] elements;private int length;//constructor with a parameter public MyString(char[] otherElements){

length = otherElements.length;elements = new char[length];for (int i = 0; i < otherElements.length; i++) {

elements[i] = otherElements[i];}

}

...}

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

השם זהה לשם המחלקה ואין

ערך החזרה

5

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

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

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

:לדוגמה

של הבנאי בשורה הראשונהבשורה הראשונההקריאה חייבת להתבצע

public MyString(MyString other){this(other.elements);

}

6

thisthis

מה היתרון בשימוש בדרך זו?

( )

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

?דוגמה נוספת: מה עושה הבנאי השני

public class MyString{private char[] elements;

  private int length;

public MyString(String s) {…

}

public MyString() {this("");…

}}

7

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

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

public class MyString{private char[] elements;private int length;

public MyString(char[] elements, int length) {

this.length = length;this.elements = new char[this.length];for (int i = 0; i < this.length; i=i+1)

this.elements[i] = elements[i];}

}

8

(.) בעזרת האופרטור

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

תזכורת )מההרצאות( – המחלקותPoint -ו Circle:

public class Point {public double x;public double y;

public Point() {x = 0;y = 0;

}

public Point(Point p) {x = p.x;y = p.y;

}}

בנאי חסר פרמטריםבנאי חסר פרמטרים

בנאי מעתיקבנאי מעתיק

9

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

public class Circle{public Point center;public double radius;

//constructorspublic 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

בנאי חסר פרמטריםבנאי חסר פרמטרים

בנאי המקבל את כל השדות

בנאי המקבל את כל השדות

10

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

public Circle(Circle other) {center = other.center;radius = other.radius;

}

:Circleבנאי מעתיק אפשרי ל- •

מה יקרה אם נבצע את הפעולות הבאות:•

.Shallow Copyהבנאי המעתיק משתמש בגישת ה- •

public static void main(String[] args){Circle circ1 = new Circle();Circle circ2 = new Circle(circ1);circ2.center.x = 4;

}

11

Copy constructor

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

public Circle(Circle other) {center = new Point(other.center);radius = other.radius;

}

:Circleבנאי מעתיק אפשרי ל- •

מה יקרה עכשיו אם נבצע את הפעולות הבאות:•

.Deep Copyהבנאי המעתיק משתמש בגישת ה- •

public static void main(String[] args){Circle circ1 = new Circle();Circle circ2 = new Circle(circ1);circ2.center.x = 4;

}

12

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

אוניברסיטת בן גוריון - מבוא למדעי המחשב 13

.ממשק מייצג רעיון מופשט( הממשקinterface-הינו כלי ב )Java למימוש

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

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

המממשות אותו.

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

14

הצהרה על ממשק:public interface <name> {

<methods list>}

ממשקים מתארים שיטות )ציבוריות( ללא ישומן.1.

( - גם אם לא publicכל השיטות בממשק הן ציבוריות )2.הוגדרו כך במפורש

הגדרת שיטה כפרטית בממשק היא טעות קומפילציה.3.

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

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

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

15

לדוגמה:public interface Predator { public boolean chasePrey(Prey p); public void eatPrey(Prey p);}

ממשקים מתארים שיטות )ציבוריות( ללא ישומן.1.

( - גם אם לא publicכל השיטות בממשק הן ציבוריות )2.הוגדרו כך במפורש

הגדרת שיטה כפרטית בממשק תגרום לטעות קומפילציה.3.

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

16

ממשק, בדומה למחלקה, מגדיר טיפוס.5.

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

:Predator להיות מסוג xלמשל, ניתן להצהיר על משתנה

Predator x;

מממשק. למשל:לא ניתן ליצור אובייקט6.

x = new Predator(); // will not compile !!!

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

17

ניתן להצהיר על מחלקה כמימוש של ממשק כך:7.

class Tiger implements Predator

שיטות הממשק )שגיאת כלמחלקה כזו צריכה לממש את 8.קומפילציה(.

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

מחלקה יכולה לממש יותר מממשק אחד! – נראה דוגמה בהמשך 9.

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

18

public interface Predator {

public boolean chasePrey(Prey p);

public void eatPrey(Prey p);

}

public class Tiger implements Predator {

public boolean chasePrey(Prey p) {

// code to chase prey p (specifically for a tiger)

return runAfterPrey(p);

}

public void eatPrey (Prey p) {

// code to eat prey p (for a tiger)

chew(p);

swallow(p);

}

...

}

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

19

public interface Predator {

public boolean chasePrey(Prey p);

public void eatPrey(Prey p);

}

public class Shark implements Predator {

public boolean chasePrey(Prey p) {

// code to chase prey p (specifically for a shark)

return swimAfterPrey(p);

}

public void eatPrey (Prey p) {

// code to eat prey p //(specifically for a shark)

bite(p);

swallow(p);

}

}

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

20

טרף" הוא גם כן תאור כללי של יצור, המסוגל לבצע מספר"פעולות בסיסיות. גם לו יהיה ממשק:

public interface Prey {public boolean isAlive();public void die();public void runAway();

}:"דוגמאות למחלקות שעשויות לממש "טרף

public class Frog implements Prey {public void jump() { ... }public void runAway() { ... }...

}

public class Deer implements Prey {...

}

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

21

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

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

Predator[] preds = new Predator[3];preds[0] = new Tiger();preds[1] = new Shark();preds[2] = new Shark(); Prey froggy = new Frog();

for (int i=0; i<preds.length && froggy.isAlive(); i=i+1) {froggy.runAway();if (preds[i].chasePrey(froggy))

preds[i].eatPrey(froggy);}

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

.interface Preyממשק של טרף –

:האם ניתן היה להפעילfroggy.jump)(

?

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

22

:אך קודם נראה דוגמה כיצד ניתן לקבל טורף וטרף כפרמטר לפונקציה

public static void simulateChase(Predator predat, Prey prey) }

prey.runAway();

if (predat.chasePrey(prey))

predat.eatPrey(prey);

}

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

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

23

Shark sharky1 = new Shark();Frog kermit1 = new Frog();simulateChase(sharky1, kermit1);

שימו לב, ניתן גם לרשום:Predator sharky2 = new Shark();Prey kermit2 = new Frog();simulateChase(sharky2, kermit2);

קובע אילו שיטות ( reference type)•טיפוס המשתנה חוקיות לביצוע עבור המשתנה )נבדק בזמן הידור(.

בזיכרון שעליו מצביע instance type)•טיפוס האובייקט )המשתנה בזמן הריצה קובע איזו שיטה תופעל )כלומר,

מאיזו מחלקה מממשת(.

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

24

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

public class Shark implements Predator {private String name;private int numOfTeeth;

public Shark(String name) {this.name = name;numOfTeeth = 3000 + (int)(Math.random()*1000);

}private void swallow(Prey p) {

p.die();}public int getNumOfTeeth() { return numOfTeeth; }public void swimForFun() { ... }

public void eatPrey (Prey p) {

bite(p);

swallow(p);

}...

}

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

25

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

אחד. אם לשתי הfoo יש אותה חתימה אך טיפוס מוחזר שונה - טעות קומפילציה. )לא ניתן

לממש את שני הממשקים יחד(.

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

public class Frog implements Prey, Predator {public boolean chasePrey(Prey p) {

...}public void eatPrey (Prey p) {

...}...

}

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

26

כעת הצפרדע יכולה לבצע את שני התפקידים:Shark sharky = new Shark();

Frog kermit = new Frog();

Fly bzzit = new Fly();

simulateChase(sharky, kermit);

if(kermit.isAlive())

simulateChase(kermit, bzzit);

sharky.swimForFun();

הערה: אף צפרדע )או זבוב( לא נפגע בהכנת התרגול

?Predator כ-sharkyהאם ניתן היה להגדיר את ?Prey כ-kermitהאם ניתן היה להגדיר את ?Prey כ-bzzitהאם ניתן היה להגדיר את

לאלאכן

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

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

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

פרמטר לא מתאים לפונקציה

27

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

IndexOutOfBoundsException:חריגה ממערך

NullPointerException:ניסיון לפעול על משתנה שאינו פרימיטיבי בעל ערך

null

28

Runtime ExceptionsRuntime Exceptions

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

29

public static void main(String[] args) {MyString str = new MyString("Hello world");str.setChar(-1, '!');

}

Exception in thread "main" java.lang.RuntimeException: Index out of boundat MyString.setChar(MyString.java:26)at Main.main(Main.java:35)

public void setChar(int index, char ch) {if (this.length <= index || index < 0) {

throw new RuntimeException("Index out of bound");

} else {this.elements[index] = ch;

}}

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

ArithmeticException:ניסיון חלוקה באפס

IndexOutOfBoundsException:חריגה ממערך

NullPointerException: ניסיון לפעול על משתנה שאינו פרימיטיבי בעל ערך

null

30

באמצעות RuntimeExceptionוראינו כי ניתן לזרוק throw

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

public class Car {private final int MAX_SPEED = 210;private final int MIN_SPEED = -20;private int speed;…public void setSpeed(int speed){

if ((speed >= MIN_SPEED) && (speed <= MAX_SPEED))this.speed = speed;

elsethrow new RuntimeException(“Illegal

speed”);}

}

31

public static void 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)

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

32

Exception

IOExceptionRuntimeExceptio

n

NullPointerException

Object

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

ע"י פקודת חריגהלייצרניתן throw המייצרת את.אירוע החריגה

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

catchו- tryהשמורות על ידי שימוש הלאה Exception את ה-להעביר◦

בכותרת הפונקציה שאנו throws במילה השמורה כותבים.

)טיפול בחריגות לא הכרחי עבור (RuntimeExceptions

33

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

public class Car {private final int MAX_SPEED = 210;private final int MIN_SPEED = -20;private int speed;…public void setSpeed(int speed) throws Exception {

if ((speed >= MIN_SPEED) && (speed <= MAX_SPEED))this.speed = speed;

elsethrow new Exception(“Illegal speed”);

}}

34

public static void main(String[] args) {Car car = new Car();car.setSpeed(100);

}

Compilation Error

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

public class Car {private final int MAX_SPEED = 210;private final int MIN_SPEED = -20;private int speed;…public void setSpeed(int speed) throws Exception {

if ((speed >= MIN_SPEED) && (speed <= MAX_SPEED))this.speed = speed;

elsethrow new Exception(“Illegal speed”);

}}

35

public static void 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 SpeedCurrent speed is 0 km/h