39
םםםםםם םםםםם םםםםם: םםםם םםםםםם םם םםםםם םםם םם םם םםםprivate – םםםם םםםםםם םםםםם םםםםםםsuper םםםםם םםםםםםםObject םםם םםםם םםםםםםםם םםםםם םםםםםםםinstanceof םםםםםםObject םםםםםםtoString, equals םםםםםםםםםםם םם םםםםםםםם1

בתרגול הקודם

  • Upload
    brie

  • View
    41

  • Download
    3

Embed Size (px)

DESCRIPTION

בתרגול הקודם. הורשה: ניתן להרחיב רק מחלקה אחת כל מה שלא private – עובר בהורשה המילה השמורה super יצירת היררכיה Object היא שורש ההיררכיה דריסה אופרטור instanceof המחלקה Object השיטות toString , equals פולימורפיזם חד כיווניות. תרגול 11. המשך תכנות מונחה עצמים. היום בתרגול. - PowerPoint PPT Presentation

Citation preview

Page 1: בתרגול הקודם

בתרגול הקודםהורשה:•

ניתן להרחיב רק מחלקה אחת– – עובר בהורשהprivateכל מה שלא –superהמילה השמורה –יצירת היררכיה––Objectהיא שורש ההיררכיה דריסה–

instanceofאופרטור •Objectהמחלקה •

toString, equalsהשיטות –

פולימורפיזם•חד כיווניות– 1

Page 2: בתרגול הקודם

11תרגול המשך תכנות מונחה עצמים

2

Page 3: בתרגול הקודם

היום בתרגול

כללי הרשאות בהורשה•מחלקות אבסטרקטיות•

3

Page 4: בתרגול הקודם

( בהורשהvisibility modifiersכללי הרשאות )

public -שדות ושיטות המוגדרים כ –public ניתנים לגישה מתוך ומחוץ למחלקה.

protected -שדות ושיטות המוגדרים כ –protected ניתנים לגישה מתוך המחלקה וממחלקות היורשות מהמחלקה, אך

אינם ניתן לגישה ממחלקות אחרות *. באותו public מתנהג כמו protected אחר. package)* ממחלקות אחרות הנמצאות ב

package)

private-שדות ושיטות המוגדרים כ – private אינם ניתנים לגישה מחוץ למחלקה. ניסיון לגשת לשדה או שיטה כזו מחוץ למחלקה

.שגיאת קומפילציהיעורר

4

Page 5: בתרגול הקודם

שיטות לא יכולות להידרס ע"י שיטה מרמת שיתוף נמוכה יותר, זו שגיאת •קומפילציה. כלומר:

private או protected עם publicלא ניתן לדרוס שיטה –private עם שיטה protectedלא ניתן לדרוס שיטה –

public class Book { public String getName() {

… }}

public class Dictionary extends Book { protected String getName() {

… } }

Compilation Error

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

לעקרון הפולימורפיזם5

Book b = new Dictionary)(;System.out.println )b.getName)( (;

( בהורשהvisibility modifiersכללי הרשאות )

Page 6: בתרגול הקודם

משתנים אינם עוברים דריסה בהורשה.• עוברות בהורשה.privateשיטות שאינן •

שיטות פרטיות נועדו למימוש פנימי של מחלקת האב, ואינן ניתנות –לשימוש ע"י תת מחלקה.

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

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

:דוגמה•עסק היא סוג של חנות–

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

כל מחלקה מומשה ע"י מתכנתת אחרת–)(calcSumבכל מחלקה מימוש שונה לשיטה פרטית - –

6

( בהורשהvisibility modifiersכללי הרשאות )

Page 7: בתרגול הקודם

public class Business {

protected Employee[] employees;protected double monthlyRent;

......

// calculates total monthly expenses

public double monthlyExpenses() {double salaries = calcSum();return this.monthlyRent + salaries;

}

// calculates monthly salaries

private double calcSum() { double sum = 0;for (int i=0; i<this.employees.length; i=i+1) {

sum = sum + this.employees[i].getSalary();}return sum;

}......}

7

קריאה לשיטה פרטית

Page 8: בתרגול הקודם

public class Shop extends Business {protected Item[] items;

......

// override: calculates total monthly expenses

public double monthlyExpenses() {double itemPrices = calcSum();return itemPrices + super.monthlyExpenses();

}// No override: calculates total item prices

private double calcSum() {double sum=0;for (int i=0; i<this.items.length; i=i+1) {

sum = sum + this.items[i].getPrice();}return sum;

}......}

8

, protected ל-calcSum: אם נשנה את המאפיין של שאלה?monthlyExpensesמה תחשב

קריאה לשיטה פרטית

Page 9: בתרגול הקודם

סיכום חוקי גישה לשיטות ושדות בהורשה :Javaב-

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

המופיעה במחלקת-אב ובתת-מחלקה, בקריאה לשיטה שאינה פרטית2.אם ע"י קריאה ישירה או ע"י שימוש באופרטור השייכות ).(, הקוד המופעל

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

.שיטת הבצל

של המחלקה בה היא מוגדרת. scope נגישה רק בתוך ה-שיטה פרטית3. בו ממוקמת scopeלפי ה-בקריאה לשיטה פרטית, הקוד המופעל נקבע

הקריאה.

)ללא אופרטור ע"י גישה ישירה )קריאה או השמה(, שדהבגישה ל4. בו ממוקמת הגישה )ומשם scopeלפי ה-השייכות(, הגישה לשדה נקבעת

בסריקה מלמטה למעלה לפי היררכית ההורשה(.

, ע"י אופרטור השייכות )קריאה או השמה( שאינו פרטי, שדהבגישה ל5. ) )reference typeבהתאם למחלקת טיפוס המשתנההגישה נקבעת

שעליה שייך השדה )ומשם בסריקה מלמטה למעלה לפי היררכית ההורשה(.

9

למה זה הגיוני?לשיטה פרטית לא ניתן לקרוא ממחלקה אחרת, לכן אם מנסים

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

Page 10: בתרגול הקודם

דוגמה להורשה

)שאלה ממבחן(

10

Page 11: בתרגול הקודם

A a = new A (1);A b = new B (2, 22);

System.out.println)a.getX)((; System.out.println)b.getX)((; System.out.println)b.superX)((;

122 Compilation Error !! )The method superX)(

is undefined for the type A(

Output / Notes

if )b instanceof B( System.out.println)b.superX)((; Compilation Error !!

11

public class A {private int x;public int y;public A)int x( {

this.x = x;this.y = 2*x;

}public int getX)( { return x; }public int doubleX)( { return 2 * getX)(; }public int tripleX)( { return 3 * x; }private int subXhelper)( { return x - 1; }public int subX)( {

return subXhelper)(; }

}

public class B extends A {private int x;public int y;public B)int xA, int xB( {

super)xA(;this.x = xB;this.y = xA + xB;

}public int getX)( { return x; }public int superX)( {

return super.getX)(;}public int tenTimesX)( { return 10*x; }private int subXhelper)( { return x-2; }

}

Page 12: בתרגול הקודם

A a = new A (1);A b = new B (2, 22); Output / Notes

12

public class A {private int x;public int y;public A)int x( {

this.x = x;this.y = 2*x;

}public int getX)( { return x; }public int doubleX)( { return 2 * getX)(; }public int tripleX)( { return 3 * x; }private int subXhelper)( { return x - 1; }public int subX)( {

return subXhelper)(; }

}

public class B extends A {private int x;public int y;public B)int xA, int xB( {

super)xA(;this.x = xB;this.y = xA + xB;

}public int getX)( { return x; }public int superX)( {

return super.getX)(;}public int tenTimesX)( { return 10*x; }private int subXhelper)( { return x-2; }

}

B bb = )B(b;System.out.println)bb.superX)((; 2

System.out.println)))B(b(.superX)((; 2System.out.println)a.tripleX)((;System.out.println)b.tripleX)((;

36

Page 13: בתרגול הקודם

System.out.println)b.subX)((;

System.out.println)))B(b(.tenTimesX)((; System.out.println)b.doubleX)((;

22044

113

public class A {private int x;public int y;public A)int x( {

this.x = x;this.y = 2*x;

}public int getX)( { return x; }public int doubleX)( { return 2 * getX)(; }public int tripleX)( { return 3 * x; }private int subXhelper)( { return x - 1; }public int subX)( {

return subXhelper)(; }

}

public class B extends A {private int x;public int y;public B)int xA, int xB( {

super)xA(;this.x = xB;this.y = xA + xB;

}public int getX)( { return x; }public int superX)( {

return super.getX)(;}public int tenTimesX)( { return 10*x; }private int subXhelper)( { return x-2; }

}

System.out.println)))B(a(.tenTimesX)((; Run-time Error: ClassCastException: A cannot be cast to B

Output / Notes

A a = new A (1);A b = new B (2, 22);

Page 14: בתרגול הקודם

14

public class A {private int x;public int y;public A)int x( {

this.x = x;this.y = 2*x;

}public int getX)( { return x; }public int doubleX)( { return 2 * getX)(; }public int tripleX)( { return 3 * x; }private int subXhelper)( { return x - 1; }public int subX)( {

return subXhelper)(; }

}

public class B extends A {private int x;public int y;public B)int xA, int xB( {

super)xA(;this.x = xB;this.y = xA + xB;

}public int getX)( { return x; }public int superX)( {

return super.getX)(;}public int tenTimesX)( { return 10*x; }private int subXhelper)( { return x-2; }

}

Output / NotesA a = new A (1);A b = new B (2, 22);

System.out.println)a.y(; System.out.println)b.y(; System.out.println)))B(b(.y(; B bb= )B(b;System.out.println)bb.y(;System.out.println)))A(bb(.y(;

2424

244

Page 15: בתרגול הקודם

מחלקות אבסטרקטיות

כאשר רוצים לחלוק קוד משותף בין מספר מחלקות למרות •שאין רצון לאפשר יצירת אובייקטים ממחלקת האב.

מחלקת האב:•מכילה קוד משותף.–קובעת אילו שיטות אבסטרקטית על תתי המחלקות לממש.–

תת-מחלקה קונקרטית מממשת שיטות אבסטרקטיות.•

15

Page 16: בתרגול הקודם

מחלקות אבסטרקטיותpublic abstract class <name> {

public abstract void <method name> ( ... );…

}

במחלקה אבסטרקטית יכולות להיות שיטות רגילות, כמו בכל •מחלקה.

להיות לה שיטות אבסטרקטיות: שיטות יכולותבנוסף •שההגדרה שלהן קיימת אבל אין להן מימוש.

אנו מכריזים על מחלקה או על שיטה כאבסטרקטית בעזרת •.abstractהמילה השמורה

16

Page 17: בתרגול הקודם

מחלקות אבסטרקטיותמחלקה אבסטרקטית - לא ניתן ליצור ממנה מופעים.•

public abstract class Game { public Game} … { )(

…}

Game g = new Game(); // Compilation error!

מחלקה שמרחיבה מחלקה אבסטרקטית ולא מממשת את כל • להיות אבסטרקטית בעצמה.חייבתהשיטות האבסטרקטיות,

17

Page 18: בתרגול הקודם

•Spy Robot רובוט מעקב( הינו רובוט הנשלט מרחוק( ומאפשר צילום תמונות ושליחתן.

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

18

Spy Robot

Page 19: בתרגול הקודם

רובוטי מעקב2נסתכל על •

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

19

Spy Robot

Page 20: בתרגול הקודם

20

Spy Robotpublic abstract class SpyRobot {

private String model;public SpyRobot(String model) {

this.model=model;}public String getModel() {

return this.model;}

public abstract void moveForward();public abstract void moveBackward();public abstract void turnLeft();public abstract void turnRight();

public void takePicture() { ... }public void chargeBattery() { ... }

}

Page 21: בתרגול הקודם

21

Roboquad – Spy Robotpublic class LegsSpyRobot extends SpyRobot {

public LegsSpyRobot() {super("Roboquad");

}

public void moveForward() {for(int i=0; i<4; i++)

this.moveLeg(i, 1);}public void moveBackward() {

for(int i=0; i<4; i++)this.moveLeg(i, -1);

}

public void turnLeft() {this.moveLeg(0,-1);this.moveLeg(1,-1);this.moveLeg(2,1);this.moveLeg(3,1);

}// direction {1=forward, -1=backward}private void moveLeg(int legId, int dir) { ... };

}

public void turnRight() {this.moveLeg(0,1);this.moveLeg(1,1);this.moveLeg(2,-1);this.moveLeg(3,-1);

}

0

12

3

Page 22: בתרגול הקודם

22

Spyke – Spy Robotpublic class WheelsSpyRobot extends SpyRobot {

public WheelsSpyRobot() {super("Spyke");

}

public void moveForward() { this.turnWheels(1,1);

}public void moveBackward() {

this.turnWheels(-1,-1); }

public void turnLeft() { this.turnWheels(0,-1);

}public void turnRight() {

this.turnWheels(-1,0); }

// direction {1=forward, 0=stop, -1=backward}private void turnWheels(int rightDir,int leftDir) { ... };// move featurespublic void waveHands() { ... }

}

Page 23: בתרגול הקודם

23

Fly – Spy Robot

האם את זה אתם כבר יכולים לממש לבד ?

Page 24: בתרגול הקודם

מחלקה אבסטרקטית ממשק

לא ניתן ליצור מופעים לא ניתן ליצור מופעים

(extendsשימוש ע"י ירושה ) ( implementsשימוש ע"י מימושו )

יכולה להכיל קוד של חלק מהשיטות הכרזה של שיטות בלי מימוש

יורשי מחלקה זו יהיו בעלי קוד משותף וכן בעלי התנהגויות שונות )השיטות

האבסטרקטיות(

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

משותף.

מחלקה יכולה לרשת מחלקה )אבסטרקטית( אחת בלבד

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

אין הגבלה על שדות (implicitlyרק קבועים סטאטיים )

24

Page 25: בתרגול הקודם

נממש משחקים מתורת המשחקים ע"י הורשה:•משחק מוגדר על ידי מערכת של פעולות אפשריות –

ושיטת ניקוד.במשחק משחקים שני שחקנים כאשר שני –

השחקנים בוחרים פעולה בו-זמנית.בהינתן שתי הבחירות של השחקנים יקבלו –

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

25

דוגמא נוספת

Page 26: בתרגול הקודם

דוגמה: אבן נייר ומספריים

בחירה מבין שלוש הפעולות האפשריות )אבן, •נייר או מספריים(.

אבן שוברת מספריים.–מספריים גוזרים נייר.–נייר עוטף אבן.–

26http://www.youtube.com/watch?v=_PUEoDYpUyQ

Page 27: בתרגול הקודם

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

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

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

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

שנה.אם שניהם ישתקו, יכנס כל אחד מהם לשנה בכלא.–

27

Page 28: בתרגול הקודם

המחלקות שעלינו לממשActionפעולה •

שם הפעולה )"אבן"(–Playerשחקן •

"(Andrea Farinaשם השחקן )" –מספר נקודות–בחירת פעולה )מהלך( מתוך קבוצת פעולות אפשריות.–

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

28

Page 29: בתרגול הקודם

מימוש המחלקה של פעולה כלליתpublic class Action {

private String name;

public Action(String name) {this.name = name;

}public String getName(){

return this.name;}public boolean equals(Object other) {

boolean ans = false;if(other instanceof Action) ans =

this.name.equals(((Action)other).name);return ans;

}

}29

Page 30: בתרגול הקודם

מימוש המחלקה של שחקן כלליpublic abstract class Player {

private String name;private int score;

public Player(String name){this.name = name;this.score = 0;

}

public abstract Action selectAction(Action[] actions);

public boolean isWinner(Player p){return (this.score > p.getScore());

}

public void updateScore(int score){this.score = this.score + score;

}

public int getScore(){ return this.score;

}} 30

Page 31: בתרגול הקודם

מימוש שחקן אקראי

public class RandomPlayer extends Player{

public RandomPlayer(String name) {super(name);

}

public Action selectAction(Action[] actions){int randIdx = (int)

(Math.random()*actions.length);return actions[randIdx];

}}

31

Page 32: בתרגול הקודם

מימוש שחקן עיקבי

public class ConsecutivePlayer extends Player {

private int lastIdx;

public ConsecutivePlayer(String name) {super(name);this.lastIdx = 0;

}

public Action selectAction(Action[] actions) {this.lastIdx = (this.lastIdx + 1) %

actions.length;return actions[this.lastIdx];

}}

32

Page 33: בתרגול הקודם

33

public abstract class Game {

private Player p1, p2;private String name; //game nameprotected Action[] actions; // the set of actions

public Game(Player p1, Player p2, String name){this.p1 = p1; this.p2 = p2; this.name = name;this.initActions();

}

// There is no real list of actions in a general game protected abstract void initActions();

משחק כללימימוש

Page 34: בתרגול הקודם

public abstract class Game {…

public void play(int turnCount) {for (int i=0; i<turnCount; i=i+1)

this.playSingleTurn();}

private void playSingleTurn() {/* the selection order is not important * as each player does not * know the choice of the other player */Action a1 = this.p1.selectAction(actions);Action a2 = this.p2.selectAction(actions);this.rewardPlayers(a1, a2);

}// There is no real scoring strategy in a general game protected abstract void rewardPlayers(Action a1, Action a2);

… 34

)המשך(משחק כללימימוש

Page 35: בתרגול הקודם

public abstract class Game {…

public Player getWinner () {if (this.p1.isWinner(this.p2))

return this.p1; else

return this.p2;}

protected Player getFirstPlayer() {return this.p1;

}

protected Player getSecondPlayer() {return this.p2;

}}

35

)המשך(משחק כללימימוש

Page 36: בתרגול הקודם

מימוש המשחק אבן נייר ומספרייםpublic class RockPaperScissors extends Game{

public RockPaperScissors(Player p1, Player p2) {super(p1, p2, "Rock Paper Scissors");

}

protected void initActions(){this.actions = new Action[3];this.actions[0] = new Action("rock");this.actions[1] = new Action("paper");this.actions[2] = new Action("scissors");

}

...

36

Page 37: בתרגול הקודם

37

protected void rewardPlayers(Action a1, Action a2) {int p1score = 0;if (!(a1.equals(a2))) {// Different actions

if ((a1.getName().equals("rock") &&a2.getName().equals("scissors"))

|| (a1.getName().equals("paper") && a2.getName().equals("rock"))

|| (a1.getName().equals("scissors") &&a2.getName().equals("paper"))) {

p1score = 1;} else {

p1score = -1;}

}this.getFirstPlayer().updateScore(p1score);this.getSecondPlayer().updateScore(-p1score);

}}

Page 38: בתרגול הקודם

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

public class PrisonerDilemmas extends Game{

public PrisonerDilemmas(Player p1, Player p2) {super(p1, p2, "Prisoner's Dilemma");

}

protected void initActions(){ this.actions = new Action[2];this.actions[0] = new Action("silent");this.actions[1] = new Action("blame");

}...

38

Page 39: בתרגול הקודם

protected void rewardPlayers(Action a1, Action a2) {if (a1.equals(a2)) { // Same actions

if (a1.getName().equals("blame") { // blame & blame

this.getFirstPlayer().updateScore(-5);

this.getSecondPlayer().updateScore(-5);} else { // silent & silent

this.getFirstPlayer().updateScore(-1);

this.getSecondPlayer().updateScore(-1);}

} else { // Different actionsif (a1.getName().equals("blame") { //

blame & silent

this.getFirstPlayer().updateScore(0);

this.getSecondPlayer().updateScore(-15);} else { // silent & blame

this.getFirstPlayer().updateScore(-15);

this.getSecondPlayer().updateScore(0);}

}}

}

39