Download presentation
Presentation is loading. Please wait.
1
אוניברסיטת בן גוריון - מבוא למדעי המחשב 1 תרגול מספר 10 ממשקים o כללים בסיסיים o מימוש מספר ממשקים o דוגמת ממשק כחוזה הורשה o כללים בסיסיים o דריסה o אופרטור instanceof
2
אוניברסיטת בן גוריון - מבוא למדעי המחשב 2 ממשקים ממשק מייצג רעיון מופשט. הממשק (interface) הינו כלי ב-Java למימוש עיקרון ההפרדה בין הכרזה למימוש. מבחינת המתכנת, הממשק הוא הצהרת כוונות או הבטחה שצריך למלא. ממשק קובע את הפונקציונאליות המשותפת לכל המחלקות הממשות אותו.
3
אוניברסיטת בן גוריון - מבוא למדעי המחשב 3 ממשקים – כללים בסיסיים הצהרה על ממשק: public interface { } 1.ממשקים מתארים שיטות (ציבוריות) ללא ישומן. 2.כל השיטות בממשק הן ציבוריות (public) - גם אם לא הוגדרו כך במפורש 3.הגדרת שיטה כפרטית בממשק היא טעות קומפילציה. הערה חשובה: המשתמש במחלקה המממשת ממשק אינו יכול לדעת את פרטי המימוש של השיטות, ואפילו רצוי שלא יצטרך לחשוב עליהם כדי שיוכל להתרכז במשימה שלפניו ולטפל בה ברמת מופשטות מתאימה.
4
אוניברסיטת בן גוריון - מבוא למדעי המחשב 4 ממשקים – כללים בסיסיים לדוגמה: public interface Predator { public boolean chasePrey(Prey p); public void eatPrey(Prey p); } 1.ממשקים מתארים שיטות (ציבוריות) ללא ישומן. 2.כל השיטות בממשק הן ציבוריות (public) - גם אם לא הוגדרו כך במפורש 3.הגדרת שיטה כפרטית בממשק היא טעות קומפילציה.
5
אוניברסיטת בן גוריון - מבוא למדעי המחשב 5 ממשקים – כללים בסיסיים 5. ממשק, בדומה למחלקה, מגדיר טיפוס. שדות, משתנים ופרמטרים יכולים להיות מוגדרים להיות מסוג ממשק. למשל, ניתן להצהיר על משתנה x להיות מסוג Predator: Predator x; 6. לא ניתן ליצור אובייקט מממשק. למשל : x = new Predator(); // will not compile !!!
6
אוניברסיטת בן גוריון - מבוא למדעי המחשב 6 ממשקים – כללים בסיסיים 7. מחלקה שמממשת ממשק צריכה לממש את כל שיטותיו. ניתן להצהיר על מחלקה להיות מממשת ממשק כך : class Tiger implements Predator 8. מחלקה כזו צריכה לממש את כל שיטות הממשק ( שגיאת קומפילציה ). יוצאות מן הכלל הזה הן מחלקות אבסטרקטיות, עליהן נדבר בהמשך הקורס. מחלקה אבסטרקטית לא חייבת לממש את כל השיטות של ממשק. 9. מחלקה יכולה לממש יותר מממשק אחד ! – נראה דוגמה בהמשך
7
אוניברסיטת בן גוריון - מבוא למדעי המחשב 7 public interface Predator { boolean chasePrey(Prey p); 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); }... }
8
אוניברסיטת בן גוריון - מבוא למדעי המחשב 8 public interface Predator { boolean chasePrey(Prey p); 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); }
9
אוניברסיטת בן גוריון - מבוא למדעי המחשב 9 "טרף" הוא גם כן תאור כללי של יצור, המסוגל לבצע מספר פעולות בסיסיות. גם לו יהיה ממשק: 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 {... }
10
אוניברסיטת בן גוריון - מבוא למדעי המחשב 10 כריש הוא טורף וגם נמר הוא טורף. בזכות הממשק המשותף אותו הם ממשים, אנחנו יכולים למשל, להחזיק מערך של טורפים ולהפעיל פעולות משותפות על כל אחד מהאיברים במערך. 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) { frog.runAway(); if (preds[i].chasePrey(froggy)) preds[i].eatPrey(froggy); } ניתן לראות שיצרנו גם טרף – צפרדע, שנרדף ע"י הכרישים והנמר. מיד נראה מה טרף מסוגל לבצע, כלומר כיצד הוגדר ממשק של טרף – interface Prey. האם ניתן היה להפעיל: froggy.jump() ?
11
אוניברסיטת בן גוריון - מבוא למדעי המחשב 11 אך קודם נראה דוגמה כיצד ניתן לקבל טורף וטרף כפרמטר לפונקציה : public static void simulateChase(Predator predat, Prey prey) { prey.runAway(); if (predat.chasePrey(prey)) predat.eatPrey(prey); } אנחנו יכולים להפעיל את הפעולות שטורף וטרף יודעים לעשות, למרות שאיננו יודעים איזה טורף או טרף קיבלנו בקריאה לפונקציה.
12
המשך אוניברסיטת בן גוריון - מבוא למדעי המחשב 12 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 בזיכרון שעליו מצביע המשתנה בזמן הריצה קובע איזו שיטה תופעל (כלומר, מאיזו מחלקה מממשת).
13
אוניברסיטת בן גוריון - מבוא למדעי המחשב 13 ניתן, כמובן, להוסיף פעולות ( שיטות ) ומצב ( שדות ) למחלקות השונות, ללא קשר לממשק אותן ממשות. לדוגמה : 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); }... }
14
אוניברסיטת בן גוריון - מבוא למדעי המחשב 14 "טרף" הוא גם כן תאור כללי של יצור, המסוגל לבצע מספר פעולות בסיסיות. נבנה לו אם כן ממשק: public interface Prey { public boolean isAlive(); public void die(); public void runAway(); } דוגמה למחלקה שעשויה לממש "טרף": public class Frog implements Prey { private boolean living; public Frog() { living = true; } public boolean isAlive() {return living;} public void die() {living = false;} public void runAway() {... } }
15
אוניברסיטת בן גוריון - מבוא למדעי המחשב 15 מימוש מספר ממשקים ניתן לממש יותר מממשק אחד. על המחלקה המיישמת לממש את הפונקציות של כל הממשקים. אם מחלקה מיישמת שני ממשקים בעלי שיטה בעלת שם זהה נניח foo אז : אם לשתי ה foo יש חתימה שונה אז המחלקה המיישמת חייבת לממש את שתיהן. אם לשתי ה foo יש אותה חתימה ואותו טיפוס מוחזר אז המחלקה מיישמת רק foo אחד. אם לשתי ה foo יש אותה חתימה אך טיפוס מוחזר שונה - טעות קומפילציה. ( לא ניתן לממש את שני הממשקים יחד ). עד עתה חשבנו על צפרדע כטרף. אבל ניתן לחשוב עליו גם כטורף ( זבובים יהיו הטרף שלו במקרה זה ) public class Frog implements Prey, Predator { public boolean chasePrey(Prey p) {... } public void eatPrey (Prey p) {... }... }
16
אוניברסיטת בן גוריון - מבוא למדעי המחשב 16 כעת הצפרדע יכולה לבצע את שני התפקידים : Shark sharky = new Shark(); Frog kermit = new Frog(); Fly bzzit = new Fly(); simulateChase(sharky, kermit); if(kermit.isAlive()) simulateChase(kermit, bzzit); sharky.swimForFun(); הערה: אף צפרדע (או זבוב) לא נפגע בהכנת התרגול האם ניתן היה להגדיר את sharky כ-Predator? האם ניתן היה להגדיר את kermit כ-Prey? האם ניתן היה להגדיר את bzzit כ-Prey? לא כן
17
אוניברסיטת בן גוריון - מבוא למדעי המחשב 17 ממשק כחוזה נגדיר ממשק ל " זוג סדור " של אובייקטים. בזוג סדור יש שני איברים : איבר ראשון ואיבר שני. ניתן להבחין בין שניהם. נרצה יכולת ליצור זוג סדור, ואחר כך לגשת לכל איבר. כמו כן נוסיף את הפעולה equals שתשווה את הזוג הסדור לזוג סדור אחר. יש מספר דרכים לממש זוג סדור. למשל בעזרת שני משתנים, first ו -second, או בעזרת מערך בגודל 2. נשים לב כי השיטה orderedEquals מקבלת זוג סדור אחר, ואיננו יודעים כיצד הוא ממומש ( שני משתנים, מערך או אחרת ). כל שאנו יכולים לעשות הוא לגשת לשיטות שהחוזה ( הממשק ) OrderedPair מספק לנו. public interface OrderedPair { public Object getFirst(); public Object getSecond(); public boolean orderedEquals(OrderedPair another); public boolean unorderedEquals(OrderedPair another); }
18
אוניברסיטת בן גוריון - מבוא למדעי המחשב 18 ממשק כחוזה public class PairAsFields implements OrderedPair { private Object first, second; public PairAsFields(Object x, Object y){ first = x; second = y; } public Object getFirst() { return first; } public Object getSecond() { return second; } public boolean orderedEquals(OrderedPair another) { return first.equals(another.getFirst()) && second.equals(another.getSecond()); } public boolean unorderedEquals(OrderedPair another) { return (getFirst().equals(another.getFirst()) && getSecond().equals(another.getSecond())) || (getFirst().equals(another.getSecond()) && getSecond().equals(another.getFirst())); }
19
אוניברסיטת בן גוריון - מבוא למדעי המחשב 19 public class PairAsArray implements OrderedPair { private Object[] pair; public PairAsArray(Object a, Object b) { pair = new Object[2]; pair[0] = a; pair[1] = b; } public Object getFirst() { return pair[0]; } public Object getSecond() { return pair[1]; } public boolean orderedEquals(OrderedPair another) { return pair[0].equals(another.getFirst()) && pair[1].equals(another.getSecond()); } public boolean unorderedEquals(OrderedPair another) { return (getFirst().equals(another.getFirst()) && getSecond().equals(another.getSecond())) || (getFirst().equals(another.getSecond()) && getSecond().equals(another.getFirst())); } ממשק כחוזה
20
אוניברסיטת בן גוריון - מבוא למדעי המחשב 20 שימוש בממשק כחוזה public class UsePairs { public static void main(String[] pars) { OrderedPair p1 = new PairAsArray("hello","goodbye"); OrderedPair p2 = new PairAsFields("goodbye","hello"); System.out.println(p1.orderedEquals(p2)); System.out.println(p1.unorderedEquals(p2)); } מה יודפס? false true
21
אוניברסיטת בן גוריון - מבוא למדעי המחשב 21 הורשה
22
אוניברסיטת בן גוריון - מבוא למדעי המחשב 22 הורשה המחלקה מתארת את מרחב המצבים ואת ההתנהגויות האפשריות לאובייקט. הורשה: הגדרת מחלקה על בסיס מחלקת אב. דוגמה: –מחלקה המגדירה אופניים תגדיר אובייקטים בעלי שני גלגלים, כידון ופדלים. –תתי מחלקות (subclasses), יורשות, מרחיבות: אופני הרים, אופני מרוץ ואופניים עם גלגלי עזר הן סוג של אופניים (עם מאפיינים ויכולות שונות). –מחלקת האופניים היא מחלקת אב של (superclass) של מחלקות אופני הרים ואופני מרוץ. אופניים אופניים עם גלגלי עזר אופני מרוץאופני הרים
23
אוניברסיטת בן גוריון - מבוא למדעי המחשב 23 הורשה כל תת מחלקה יורשת ממחלקת האב שלה התנהגות ומאפייני מצב. לכל מחלקות האופניים קיימים: –מאפייני מצב (שדות) משותפים כמו: מהירות מקסימלית, צבע –התנהגויות (שיטות) משותפות כמו: עצירה, נסיעה, החלפת הילוכים. התנהגות תתי המחלקות אינה מוגבלת להתנהגות מחלקת האב. תתי מחלקות יכולות להוסיף שדות ושיטות משלהן, למשל: –אופני הרים יכולות לנסוע בשטח –לאופניים עם גלגלי עזר יש גלגלי עזר, וכו'. אופניים אופניים עם גלגלי עזר אופני מרוץאופני הרים
24
אוניברסיטת בן גוריון - מבוא למדעי המחשב 24 הורשה ככל שנוסיף התנהגויות ומשתני מצב נהפוך את המחלקה לספציפית יותר (כללית פחות). –ככל שיורדים בעץ ההורשות, כך המחלקה יותר ספציפית. –אופני מרוץ מגדירים קבוצה מדויקת יותר מאשר אופניים כלליים. תתי מחלקות יכולות לדרוס את השיטות אותן הן יורשות. –שיטת החלפת הילוכים אשר קיימת במחלקה אופניים, תהיה שונה עבור מחלקת אופני מרוץ אשר יש להם הילוכים מיוחדים, וכו' הורשה אינה מוגבלת לרמה אחת. ניתן להגדיר תת מחלקות עבור תת המחלקות וכן הלאה. –אופני הרים מושלגים אופניים אופניים עם גלגלי עזר אופני מרוץאופני הרים מושלגים
25
אוניברסיטת בן גוריון - מבוא למדעי המחשב 25 הורשה - כללים רשימת כללים להורשה 1. מחלקה יכולה להרחיב (לַרשת) רק מחלקה אחת. (ניתן להשתמש בממשקים אם יש צורך בהתנהגויות מרובות) אופניים עם גלגלי עזר אופנייםמשחקי ילדים
26
אוניברסיטת בן גוריון - מבוא למדעי המחשב 26 הורשה - כללים 2. מחלקה B תרחיב את A אם נכון לומר "B הוא סוג של A". ב-Java נכתוב: class B extends A אופני מרוץ אופניים A B
27
אוניברסיטת בן גוריון - מבוא למדעי המחשב 27 הורשה - כללים 3. אובייקט מרחיב (מטיפוס B) מכיל בתוכו את האובייקט המורחב (מטיפוס A). 4. A היא ה parent class או ה super class של B B היא ה subclass או child class של A אופני מרוץ אופניים A B אופני מרוץ - public void race() אופניים - color = Red - speed = 50 km/h - public void ride()
28
אוניברסיטת בן גוריון - מבוא למדעי המחשב 28 הורשה - כללים 5. B יורשת את כל השיטות והמשתנים שאינם private ב-A מלבד הבנאים. לא ניתן לגשת בתוך B לשיטות או שדות פרטיים ב-A על אף שהם קיימים (עבור שיטות נראה דוגמה בהמשך הקורס, כשנדבר על protected) class A { private int aNum; } class B extends A { private int bNum; public B() { aNum=0; bNum = 0; } // compilation error
29
אוניברסיטת בן גוריון - מבוא למדעי המחשב 29 הורשה - כללים 6. בנאים אינם עוברים בהורשה! לכן יש להגדיר בנאים חדשים 7. כשיוצרים אובייקט חדש מסוג B, הבנאי של מחלקה A חייב להיקרא. –ניתן לקרוא לו באופן מפורש, אחרת נקרא באופן אוטומטי הבנאי ללא- פרמטרים של A. –קריאה מפורשת נעשית ע"י super(…). super הינה מלה שמורה בשפת Java,אשר מייצגת את מחלקת האב. class A { private int aNum; public A(int n) { aNum = n; } class B extends A { private int bNum; public B() { super(0); bNum = 0; } //calls the constructor of A
30
אוניברסיטת בן גוריון - מבוא למדעי המחשב 30 הורשה - כללים מה קורה במקרה זה? class A { private int aNum; public A(int n) { aNum = n; } class B extends A { private int bNum; public B() { bNum = 0; } זו שגיאת קומפילציה! no empty constructor for A: Cannot find symbol: constructor A()
31
אוניברסיטת בן גוריון - מבוא למדעי המחשב 31 הורשה - כללים 8. הקריאה ל super חייבת להיות השורה הראשונה בבנאי של B מה קורה במקרה זה? class A { private int aNum; public A(int n) { aNum = n; } class B extends A { private int bNum; public B() { bNum = 0; super(0); } 1. Cannot find symbol: constructor A() 2. Call to super must be first statement in constructor הקומפיילר יראה זאת כ- 2 שגיאות קומפילציה!
32
אוניברסיטת בן גוריון - מבוא למדעי המחשב 32 הורשה - כללים 9.דריסה – Overriding דריסה תתרחש כאשר מחלקת הבן מגדירה שיטה בעלת חתימה זהה לשיטה המוגדרת במחלקת האב – כאשר מדובר בדריסה, הטיפוס של המופע (instance) – מה שנמצא בקצה החץ בטלבלת המשתנים והזכרון – מגדיר איזו פונקציה תופעל. – במקרים אחרים מופעלת הפונקציה לפי הרפרנס (reference) – מה שרשום כטיפוס המשתנה בטבלת המשתנים – דריסה תתרחש רק בשיטות שאינן private. 10. super - אם רוצים לקרוא באופן מפורש לפונקציה של האב ניתן להשתמש במילה super.
33
אוניברסיטת בן גוריון - מבוא למדעי המחשב 33 הורשה - כללים 11.( העמסה ) vs. Overloading Overriding ( דריסה ) –העמסה היא כאשר ישנן מספר הגדרות לפונקציה בעלת אותו שם אך עם פרמטרים שונים באותה המחלקה. –דריסה היא הגדרה של שתי שיטות בעלות חתימה זהה, אחת המחלקת האב ואחת במחלקת הבן. –העמסה מאפשרת פעולה דומה עבור data שונה –דריסה מאפשרת לבצע פעולה דומה עבור טיפוס אובייקט שונה.
34
אוניברסיטת בן גוריון - מבוא למדעי המחשב 34 הורשה - כללים 12. ניתן ליצור הירארכיה בעזרת הורשה, כך שמחלקת בן של מחלקה אחת יכולה להיות מחלקת אב של מחלקה אחרת. אופניים אופניים עם גלגלי עזר אופני מרוץאופני הרים מושלגים
35
אוניברסיטת בן גוריון - מבוא למדעי המחשב 35 הורשה - כללים 13. כל מחלקה מרחיבה בצורה ישירה או עקיפה את המחלקה Object, והיא השורש בהירארכית הירושה. Object אופניים אופניים עם גלגלי עזר אופני מרוץאופני הרים מושלגים
36
אוניברסיטת בן גוריון - מבוא למדעי המחשב 36 הורשה - כללים 14.במחלקה Object מוגדרים המימושים הדיפולטיביים (ברירות המחדל, מן המילה default) של השיטות toString, equals ועוד –public String toString() –public boolean equals(Object obj) ולכן שיטות אלו נורשות אוטומטית ע"י מחלקה שאנו מגדירים ?? מה יקרה אם נגדיר עבור מחלקה A את השיטה הבאה: ?? public boolean equals(A other) !! לא ביצענו דריסה של השיטה equals של מחלקת האב Object, מאחר והחתימה שונה.
37
אוניברסיטת בן גוריון - מבוא למדעי המחשב 37 class A { private int aNum; public A(int n) { aNum = n; } public void inc(int n){ aNum = aNum + n; } class B extends A{ private int bNum; public B() { super(0); bNum = 0; } public void inc(int amount){ // overrides inc(int) of A super.inc(amount); //increment aNum bNum += amount; //increment bNum } B - bNum = 16 - void inc(int) A - aNum = 10 - void inc(int) דוגמה 1:
38
אוניברסיטת בן גוריון - מבוא למדעי המחשב 38 class A { private int aNum; public A(int n) { aNum = n; } public void inc(int n){ aNum = aNum + n; } class B extends A{ private int bNum; public B() { super(0); bNum = 0; } public int inc(int amount){ // compilation error! Cannot override! super.inc(amount); bNum += amount; return bNum; } B - bNum = 16 - int inc(int) A - aNum = 10 - void inc(int) - לא ניתן לדרוס שיטה עם חתימה זהה וטיפוס החזרה שונה: דוגמה 2: הערה: זה חוקי כאשר טיפוס ההחזרה הוא אובייקט ויורש מטיפוס ההחזרה של השיטה הנדרסת, אך לא רצוי בכל מקרה 38
39
אוניברסיטת בן גוריון - מבוא למדעי המחשב 39 הורשה - כללים 15. אופרטור instanceof: זהו אופרטור המחזיר true אם ורק אם האובייקט משמאלו הוא מופע (instance) של המחלקה מימינו של האופרטור. דוגמאות : class Cat{} interface ShowAnimal {} class Siamese extends Cat implements ShowAnimal{}
40
אוניברסיטת בן גוריון - מבוא למדעי המחשב 40 הורשה - כללים class Cat{} interface ShowAnimal {} class Siamese extends Cat implements ShowAnimal{} System.out.println(myaoo instanceof Cat); System.out.println(mitzi instanceof Cat); System.out.println(myaoo instanceof "Cat"); Cat myaoo = new Cat(); Cat mitzi = new Siamese(); System.out.println(mitzi instanceof Siamese); System.out.println(myaoo instanceof Siamese); System.out.println(mitzi instanceof ShowAnimal); System.out.println(mitzi instanceof Object); //true //Compilation Error //true //false //true
41
אוניברסיטת בן גוריון - מבוא למדעי המחשב 41 הורשה - כללים class Cat{} interface ShowAnimal {} class Siamese extends Cat implements ShowAnimal{} System.out.println(mitzi instanceof myaoo); Cat myaoo = new Cat(); Cat mitzi = new Siamese(); System.out.println(!mitzi instanceof Cat); Cat pitzi = null; System.out.println(pitzi instanceof Cat); System.out.println(null instanceof String); //Compilation Error //Compilation Error: // operator ! cannot be applied to Cat //false System.out.println(!(mitzi instanceof Cat));
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.