Presentation is loading. Please wait.

Presentation is loading. Please wait.

מבוא למדעי המחשב הרצאה 18: פולימורפיזם ומחלקות אבסטרקטיות 1.

Similar presentations


Presentation on theme: "מבוא למדעי המחשב הרצאה 18: פולימורפיזם ומחלקות אבסטרקטיות 1."— Presentation transcript:

1 מבוא למדעי המחשב הרצאה 18: פולימורפיזם ומחלקות אבסטרקטיות 1

2 class Student public class Student { private static final int COURSE_PRICE = 1000; private String name; private int id; private int numOfCourses; public Student(int id, String name) { this.name = name; this.id = id; numOfCourses= 0; } public int computeTuition(){ return numOfCourses * COURSE_PRICE; } public void setNumOfCourses(int c) { numOfCourses = c; } … } //class Student 2

3 class Milgay public class Milgay extends Student { private int milga; public Milgay(int id, String name, int milga){ super(id, name); this.milga= milga; } public int computeTuition(){ return Math.max(0, super.computeTuition() – milga); } … } //class Milgay 3

4 הסטודנטים מוחים על שכר הלימוד עקב מחאה של אגודת הסטודנטים החליטה האוניברסיטה להגיע עם הסטודנטים להסדר ולשנות את מנגנון התשלומים, כך שהתשלום המקסימאלי לסטודנט הוא 2500 ₪ נוסיף למחלקה Student את הקבוע החדש MAX_PRICE, ואת השיטה computePayment() אשר תחשב את שכר הלימוד החדש 4

5 class Student public class Student { private static final int COURSE_PRICE = 1000; private static final int MAX_PRICE = 2500; private String name; private int id; private int numOfCourses; public Student(int id, String name) { this.name = name; this.id = id; numOfCourses= 0; } public int computeTuition (){ return numOfCourses * COURSE_PRICE; } public void setNumOfCourses(int c) { numOfCourses = c; } public int computePayment(){ return Math.min(MAX_PRICE, computeTuition()); } } //class Student 5

6 השפעת השינוי על סטודנט עתה נריץ את הקוד הבא : Student s = new Student(11,"Dani"); s.setNumOfCourses(3); System.out.println(s. getName() + " should pay " + s.computePayment()); הסטודנט יידרש לשלם 2500 ₪ במקום 3000 ₪, וכולם מרוצים. 6

7 השפעת השינוי על מלגאי עתה נריץ את הקוד הבא : Milgay m = new Milgay(12, "Moshe", 750); m.setNumOfCourses(3); System.out.println(m. getName() + “ should pay " + m.computePayment()); כמה ישלם המלגאי ? 7

8 השפעת השינוי על מלגאי - פולימורפיזם נבחן שתי אפשרויות : אם computePayment יקרא ל - computeTuition של Student יחושב שכר לימוד של 3000 ₪ וכתוצאה מחישוב המינימום ישלם הסטודנט 2500 ₪. אם computePayment יקרא ל - computeTuition של Milgay יחושב שכר לימוד של 2250 ₪ וכתוצאה מחישוב המינימום ישלם הסטודנט 2250 ₪. אם האפשרות הראשונה נכונה, סביר שהמלגאי יכעס על יו " ר האגודה, שגרם לו לשלם 250 ₪ יותר האפשרות הנכונה היא השנייה ( ליו " ר שלום...) 8

9 הסתרה של משתנים – עולם אחר נוסיף את השדה הבא גם ל -Student וגם ל -Milgay: private int grade; בנוסף, נוסיף למחלקה Student את הקוד : return grade;} } public int getGrade() ולמחלקה Milgay את הקוד : this.grade = grade;}} public void setGrade(int grade) עתה נריץ את השורות הבאות ב -main: m.setGrade(100); System.out.println(m.getName() + “ grade is " + m. getGrade()); מנגנון הפולימורפיזם לא פועל עבור משתנים ( גם לא עבור ציבוריים...) 9 0 ???

10 ומה לגבי שיטות private? נוסיף ל -Student את השיטות : public void printClassName () {System.out.println(className());} private String className(){return “Student";} ול -Milgay נוסיף את השיטה : private String className(){return “Milgay";} ונריץ את הקוד הבא : m.printClassName(); מנגנון הפולימורפיזם לא פועל בשיטות פרטיות 10 student

11 ההרשאה protected אם כמתכנתי המחלקה Student אנו רוצים לאפשר למחלקות יורשות את הגישה למשתנה מחלקה כלשהו (numOfCourses ו - COURSE_PRICE במקרה שלנו ) אך עדיין איננו מעוניינים לחשוף משתנה זה למשתמשים חיצוניים, ניתן לתת למשתנה זה את מציין ההרשאה protected 11

12 class Student public class Student { protected static final int COURSE_PRICE = 1000; private String name; private int id; protected int numOfCourses; public Student(int id, String name) { this.name = name; this.id = id; numOfCourses= 0; } public int computeTuition(){ return numOfCourses * COURSE_PRICE; } public void setNumOfCourses(int c) { numOfCourses = c; } … } //class Student 12

13 class Milgay public class Milgay extends Student { private int milga; public Milgay(int id, String name, int milga){ super(id, name); this.milga= milga; } public int computeTuitionFee(){ return (numOfCourses * COURSE_PRICE) - milga; } … } //class Milgay 13

14 מחלקות אבסטרקטיות רוצים לכתוב קוד המייצג מיכלים מסוגים שונים צורות שונות : קופסא, חבית, קובייה שיטות : משותפות : הוספת נוזל, תכולה, האם מלא ? שונות : בנאים, חישוב קיבולת האם ירושה מתאימה במקרה כזה ? האם יש אובייקט ממשי שנקרא מיכל ? 14

15 אולי ממשקים יעזרו ? public interface Tank { public double capacity(); public double getContent(); public void fill(double amount); public boolean isFull(); } 15

16 קופסא public class Box implements Tank { private double contents; private double length; private double width; private double height; //… (constructors) public void fill(double amount){ contents = Math.min(contents + amount, capacity()); } public double getContents(){ return contents; } 16

17 קופסא public boolean isFull(){ return (contents == capacity()); } public double capacity(){ return length*width*height; } } //class Box 17

18 חבית public class Cylinder implements Tank{ private double contents; private double radius; private double height; //… (constructors) public void fill(double amount){ contents = Math.min(contents + amount, capacity()); } public double getContents(){ return contents; } 18

19 חבית public boolean isFull(){ return (contents == capacity()); } public double capacity(){ return height * Math.PI * radius * radius; } }//class Cylinder 19

20 חסרון : אותו הקוד מופיע במספר מחלקות 20

21 הפתרון : מחלקות מופשטות public abstract class Tank{ private double contents; public abstract double capacity(); 21

22 הפתרון : מחלקות מופשטות public abstract class Tank{ private double contents; public Tank(){ contents = 0; } public abstract double capacity(); 22

23 public void fill(double amount){ contents = Math.min(contents + amount, capacity()); } public double getContents(){ return contents; } public boolean isFull(){ return contents == capacity(); } } // class Tank 23

24 עכשיו ניתן להשתמש בהורשה public class Cylinder extends Tank{ private double radius; private double height; public Cylinder(double radius, double height){ super(); this.radius = radius; this.height = height; } public double capacity(){ return height * Math.PI * radius * radius; } } 24

25 קופסא class Box extends Tank{ private double length; private double width; private double height; public Box(double length, double width, double height){ super(); this.length = length; this.width = width; this.height = height; } public double capacity(){ return length * width * height; } } 25

26 קובייה היא גם קופסא class Cube extends Box{ public Cube(double side){ super(side, side, side); } 26

27 ומה אם ? public class Tank{ private double contents; public Tank(){ contents = 0; } public abstract double capacity(); Tank should be declared abstract; it does not define capacity() in Tank 27

28 ומה אם ? public abstract class Tank{ private double contents; public Tank(){ contents = 0; } public double capacity(); missing method body, or declare abstract 28

29 public class Cylinder extends Tank{ private double radius; private double height; public Cylinder(double radius, double height){ super(); this.radius = radius; this.height = height; } ומה אם ? Cylinder should be declared abstract; it does not define capacity() in Tank 29

30 Tank t1 = new Cube(5); Tank t2 = new Tank(); ומה קורה כשמנסים ליצור מופע ? לא ניתן ליצור מופע של מחלקה אבסטרקטית! 30 X √

31 גם כאן אפשר protected 31 נניח כי אנו רוצים לאפשר למחלקות היורשות מ -Tank גישה ישירה לשדה contents: public abstract class Tank{ protected double contents; … }

32 גם שיטות יכולות להיות protected 32 נניח כי אנו רוצים לדרוס ב -Tank את toString, כך שהמחרוזת המודפסת תכלול את סוג המיכל, קיבולתו ותוכנו : public abstract class Tank{ … public String toString(){ return concreteClassName() + ", capacity: " + capacity() + ", contents: " + contents; } protected abstract String concreteClassName(); }// class Tank

33 ועתה נתקן את המחלקות היורשות... 33 public class Box extends Tank{ … protected String concreteTankClassName() { return "Box"; } }//class Box public class Cylinder extends Tank{ … protected String concreteTankClassName() { return "Cylinder"; } }//class Cylinder

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

35 גן החיות שלנו חיה ציפור יונק חתולכלב 35

36 ההגדרה של חיה public abstract class Animal { private String name; public String getName(){return name;} public Animal (String name){ this.name = name; } abstract public void eat(); abstract public void speak(); } 36

37 ציפור public class Bird extends Animal { public Bird(String name){ super(name); } public void eat(){ System.out.println(getName()+" eats Bissli"); } public void speak(){ System.out.println("Twit twit"); } } 37

38 יונק public abstract class Mammal extends Animal { public Mammal(String name){ super(name); } public void mammalSpecial(){ System.out.println("I’m a mammal!"); } } 38

39 כלב public class Dog extends Mammal { public Dog(String name){ super(name); } public void eat(){ System.out.println(getName()+" eats Dogli"); } public void speak(){ System.out.println("Wouf!"); } } 39

40 חתול public class Cat extends Mammal { public Cat(String name){ super(name); } public void eat(){ System.out.println(getName()+" eats Catli"); } public void speak(){ System.out.println("Meow"); } public void purr(){ System.out.println("Purr"); } } 40

41 הקמת הגן Scanner sc = new Scanner(System.in); Animal[] zoo = new Animal [10]; for (int i=0; i<zoo.length; i= i+1){ System.out.println("What animal do you want?"); String type = sc.next(); System.out.println(“How would you like to call it?"); if (type.equals("Dog")) zoo[i] = new Dog(sc.next()); else if (type.equals("Cat")) zoo[i] = new Cat(sc.next()); else zoo[i] = new Bird(sc.next()); } 41

42 אוכל וסיפור for (int i=0; i<zoo.length; i= i+1){ zoo[i].eat(); zoo[i].speak(); if (zoo[i] instanceof Mammal){ ((Mammal)zoo[i]).mammalSpecial(); if (zoo[i] instanceof Cat) ((Cat)zoo[i]).purr(); } } 42


Download ppt "מבוא למדעי המחשב הרצאה 18: פולימורפיזם ומחלקות אבסטרקטיות 1."

Similar presentations


Ads by Google