interface םיקשממ - bguintro142/wiki.files/class16... · 2014-03-01 · , java.lang ( package...
TRANSCRIPT
Interface ממשקים
1
ראינו כי ניתן לשמור אובייקטים במערכים באותו •. אופן כמו משתנים רגילים
ננסה כעת לראות כיצד למיין מערך של אובייקטים •.מסוג מסוים.מסוג מסוים
Car–ו Student, נשתמש בשתי מחלקות חדשות•
2
Student public class Student {
// Sate:private String name;private int id;
// Constructors:// Constructors:public Student(int id, String name) {
this.name = name; this.id = id;
}
// Behavior:…
} // class Student
3
Car public class Car {// Sate:private String company;private int model;
// Constructors:// Constructors:public Car(int model, String company) {
this.company = company; this.model = model;
}
// Behavior:…
} // class Car
4
נתבונן במערך של מצביעים לאוביקטים מטיפוס Students:
Students[] arr = new Student[10];Students[] arr = new Student[10];
על מנת למיין אותו נבחר אחד מאלגוריתמי המיון InsertionSortלמשל , שלמדנו
5
insertionSort
public static void insertionSort(int[] array){
for (int i=1; i<array.length; i=i+1){int value = array[i];int j = i;while(j>0 && (array[j-1] > value) ){while(j>0 && (array[j-1] > value) ){
array[j] = array[j-1];j = j-1;
}array[j] = value;
}//for}//insertionSort
6
מעבר למיון סטודנטים
מהו הקושי העיקרי בשינוי הפונקציה כדי שתתאים •?למיון סטודנטים
array[j-1] > value: פעולת ההשוואה כמובן
הפעולה הראשונה שצריך לעשות היא להחליט על הפעולה הראשונה שצריך לעשות היא להחליט על השוואת מספר תעודת , למשל. פעולת ההשוואה
.הזהות:עכשיו ניתן לכתוב
7
מיון סטודנטיםpublic static void insertionSort(Student[]
array){for (int i=1; i<array.length; i = i+1){
Student value = array[i];int j = i;while(j>0 && (array[j-1].getId() >
value.getId())){while(j>0 && (array[j-1].getId() >
value.getId())){array[j] = array[j-1];j = j-1;
}array[j] = value;
}}//insertionSort(Student[] array)
8
:עכשיו ניתן להפעיל•Students[] arr=new Student[10];insertionSort(arr);
?Carומה עם Car[] arr=new Car[10];insertionSort(arr);//????
9
מיון מכוניותpublic static void insertionSort(Car[]
array){for (int i=1; i<array.length; i = i+1){
Car value = array[i];int j = i;while(j>0 && (array[j-1].getModel() >
value.getModel()) ){while(j>0 && (array[j-1].getModel() >
value.getModel()) ){array[j] = array[j-1];j = j-1;
}array[j] = value;
}}//insertionSort(Car[] array)
10
...Objectכמובן ? אז מה פתרון אפשרי
public static void insertionSort(Object[] array){
for (int i=1; i<array.length; i=i+1){Object value = array[i];int j = i;while(j>0 && (array[j].???? > value. while(j>0 && (array[j].???? > value.
????) ){array[j] = array[j-1];j = j-1;
}array[j] = value;
}}//insertionSort
11
Interface -ממשק
היינו רוצים להגיד שכל ? אז כיצד נפתור זאת•מיון יוכל להשתמש -אובייקט שרוצה להיות בר
ראינו רעיון דומה עם . בפונקציית המיון הזאתequals בObjectSet...
" השוואה-בר"אם היתה לנו דרך להוסיף תכונת •היינו בדרך , לכל אובייקט שאנו רוצים למיין
.הנכונהקיים המושג ממשק JAVAב , בדיוק למטרה זו•
)interface(
12
התנהגותממשק הוא הגדרת ללא מימוש
13
Comparableהממשק public interface Comparable {
/*** @param other an object to compare with this* Comparable object* @return a negative value, 0, or a positive value,* if this object has a lower, an identical, or a* higher rank in the order, respectively.*/public int compareTo(Object other);
}
14
Comparableהממשק
-בר"הגדרנו את התכונה תכונה , בדוגמה שלנו•":השוואה
public int compareTo(Object other);
.היא חסרת מימוש compareToשימו לב כי השיטה •תחזיר מספר שלילי אם מקומו compareToהשיטה •
של האובייקט היוזם את הקריאה בסידור קודם למקום מספר חיובי אם מקומו , האובייקט המתקבל כפרמטר
.ואפס אם מקומם זהה, מאוחר
15
:יש לו שני צדדים, וככל חוזה, חוזהממשק הוא •ובמקרה , כל מחלקה יכולה להתחייב לממש את החוזה–
כזה היא מחוייבת לממש את כל השיטות המפורטות .בחוזה.בחוזה
ניתן להתייחס באופן אחיד למופעים של מחלקות –מבלי לדעת מהן המחלקות המממשות חוזה מסוים
התייחסות כזו מאפשרת להפעיל . הקונקרטיות שלהם.על מופעים אלו את כל השיטות המופיעות בחוזה
16
חייב לממש את כל " השוואה-בר"מי שרוצה להיות בעל התכונה :לא יעבור קומפילציה, אחרת. השיטות המופיעות בממשק
public class Student implements Comparable{
…
public int compareTo(Object other) {public int compareTo(Object other) {int otherId = ((Student)other).getId();return id - otherId;
}
} // class Student
17
יותר" מקצועי"פתרון
public class Student implements Comparable{…public int compareTo(Object other) {
if (!(other instanceof Student)){throw new RuntimeException( throw new RuntimeException(
"CompareTo got a non-Student parameter.");
}int otherId = ((Student)other).getId();return id - otherId;
}} // class Student18
במקרה זה . סידור לקסיקוגרפי לפי שם–אפשרות שנייה :Stringשל compareToניתן להשתמש בשיטה
public class Student implements Comparable{…public int compareTo(Object other) {
if (!(other instanceof Student)){throw new RuntimeException( throw new RuntimeException(
"CompareTo got a non-Student parameter.");
}String otherName =
((Student)other).getName();return name.compareTo(otherName);
}} // class Student19
:Carועבור המחלקה
public class Car implements Comparable{…public int compareTo(Object other){
if (!(other instanceof Car)){throw new RuntimeException("CompareTo
got a non-Car parameter.");got a non-Car parameter.");}
int otherModel = ((Car)other).getModel();return model - otherModel;
}} // class Car
20
בני השוואההם Studentוגם העצמים במחלקה Carעכשיו העצמים במחלקה •
" חתמו על החוזה"שתי המחלקות –כלומר (השוואה -בניComparable.(
, אשר הטיפוס שלהם הוא ממשק מצביעיםניתן להגדיר JAVAב •לפי התכונות המחייבות אותו המוצבעובכך להתייחס לאובייקט
גם אנחנו מתייחסים –רעיון זה אינו מופרך . אשר מופיעות בממשק גם אנחנו מתייחסים –רעיון זה אינו מופרך . אשר מופיעות בממשקולפעמים , לפעמים לתכונות ספציפיות של סטודנט או מרצה
.אדם-לתכונות משותפות של שניהם כבני:לכן•
Student s = new Student("shlomo",124);Comparable c = s;
,או למשלComparable c = new Student("shlomo",124);
21
:שימו לב כי לא ניתו ליצור אובייקט מטיפוס ממשק•Comparable c = new Comparable();
.ולא מחלקה, כ תכונה"היא בסה Comparable–הסיבה היא פשוטה •
public static void func(Comparable c){…}
Car car1 = new Car(2004, "Toyota");Comparable car2 = new Car(1990, "Mercedes");Point p = new Point(1,1);Object car3 = new Car(1982, "Lada");func(car2);func(car1);func(p);func(car3);func((Comparable) car3);func((Comparable) p);Car3 = p;
func((Comparable) car3);22
Sorting both Students and Carspublic static void main(String[] args) {
Student[] myStudents = new Student[2]; myStudents[0] = new Student(2, "Vika");myStudents[1] = new Student(1, "Dan");System.out.println(arr2String(myStudents));insertionSort(myStudents);System.out.println(arr2String(myStudents));
Car c1 = new Car(2004, "Toyota");Car c2 = new Car(1990, "Mercedes");Car[] myCars = {c1,c2};System.out.println(arr2String(myCars));insertionSort(myCars); System.out.println(arr2String(myCars));
}
23
:עכשיו נחזור למיון
public static void insertionSort(Comparable[] array){
Comparable value;for (int i=1; i < array.length; i = i+1){
value = array[i];int j = i;while(j>0 && while(j>0 &&
array[j-1].compareTo(value) > 0){array[j] = array[j-1];j = j-1;
}array[j] = value;
}}//insertionSort(Comparable[] array)
24
:נקודות נוספות לדיון ומחשבה, package (java.lang(הממשק שהגדרנו קיים בחבילה •
למשל (מממשות אותו java-וחלק מהמחלקות המובנות בString.(
לפי הטיפוס של ? אילו שיטות ניתן להפעיל על עצם•.castingאלא אם כן עשינו , המצביע .castingאלא אם כן עשינו , המצביע
.ממשק יכול להגדיר יותר משיטה אחת•:מחלקה יכולה לממש יותר ממשק אחד•
public class Car implementsComparable, Vehicle{…}
, תיקון באגים, אינטגרציה–ממשקים והנדסת תוכנה • .חשיבה עתידית וגמישות
25
כמובן שבאותו . InsertionSortראינו מימוש של •.וכו MergeSort, BubbleSortהאופן קיימים
נניח שנרצה למיין במספר אופנים שונים בתוכנית •.שלנו
?במחלקה אחת? היכן נמקם את השיטות הללו•
public class sortAlgorithms{public static void InsertionSort(Comparable[] arr);public static void MergeSort(Comparable[] arr);
… }26
Sorter
public interface Sorter{public void sort(Comparable[] array);
}
כל מי שרוצה להוסיף שיטת מיון חדשה צריך , עכשיו כל מי שרוצה להוסיף שיטת מיון חדשה צריך , עכשיו:Sorterפשוט לממש את הממשק
27
class InsertionSorter implements Sorter{public void sort(Comparable[] array){…}
}//class
class MergeSorter implements Sorter{public void sort(Comparable[] array){…}
}//class
28
:דוגמה
Sorter s1= new InsertionSorter();Student[] sArr=new Student[2];sArr[0]=new Student(2352452,"david");sArr[1]=new Student(111252,"Anat");s1.sort(sArr);s1.sort(sArr);Sorter s2= new MergeSorter();Car[] cArr=new Car[2];cArr[0]=new Car(2004,"toyota");cArr[1]=new Car(1943,"Ford");s2.sort(cArr);
29
Interface Replicable
מוטיבציה
x y
getX()getY()
x y
getX()getY()
x y
getX()getY()
שני עצמים זהים–מצב בלתי חוקי שני עצמים זהים–מצב בלתי חוקי .בקבוצה) שלהם equalsלפי שיטת (
add-נובע מכך ששמרנו במצביע לאובייקט המקורי
30
public void add(Object o){if ((o != null) && !contains(o) &&
(size<elements.length)){elements[size] = o;elements[size] = o;size = size + 1;
}}//add
31
Interface Replicable
מוטיבציה
x y
getX()getY()
x y
getX()getY()
x y
getX()getY()
נרצה שבקבוצה יאוכסנו רק עותקים של שאפשר יהיה להגיע אליהם רק . העצמים
.דרך השיטות של הקבוצה
לא ייצור את האובייקט new Object? מה הבעיה32בזמן ריצה–שאני באמת רוצה
public void add(Object o){if ((o != null) && !contains(o) &&
(size<elements.length)){elements[size] = new Object(o);elements[size] = new Object(o);size = size + 1;
}}//add
33
Replicable
-בר"אשר כל מי שמממש אותו הוא , Replicableנגדיר ממשק •לממשק זה תהיה שיטה אחת בלבד אשר תחזיר עותק ". הכפלה
:של האובייקט
public interface Replicable {public interface Replicable {/*** @return a replicate of this object.*/public Object replicate();
}
34
:Pointנסתכל לדוגמה על המחלקה
public class Point implements Replicable {…public Object replicate(){
return new Point(this);return new Point(this);}
}
35
ReplicableObjectSet
. ReplicableObjectSetוכעת נגדיר מחלקה •מחלקה זו תהיה זהה לחלוטין למחלקה
ObjectSet ,אך תכלול שני הבדלים:
נקבל Objectפרמטר מסוג addבמקום לקבל בשיטה –.Replicableפרמטר מסוג
הקבוצה תחזיק עותקים של האוביקטים שהכנסנו –לגורמים חיצוניים לא תיהיה . ולא את המקוריים, אליה
.גישה ישירה אל אברי הקבוצה
36
ReplicableObjectSet
public class ReplicableObjectSet {…
public void add(Replicable o){if ((o != null) && !contains(o) && if ((o != null) && !contains(o) &&
(size<elements.length)){elements[size] = o.replicate();size = size + 1;
}}//add
37