ה ו ר ש ה( י ר ו ש ה מ ת ק ד מ ת "" Java ת ו כ נ ה 1 ב ש פ ת ש י ע ו ר מ ס פ ר : 11 (III בית הספר למדעי המחשב
ב ש י ע ו ר ה י ו ם א ו ס פ י ם ג נ ר י י ם ע ו ד ע ל Geerics ה ה ע מ ס ו י ר ו ש ה ב ח י נ ה 2
א ו ס פ י ם ג נ ר י י ם ת ו כ נ ה 1 בשפת 3 Java
HashSet class Poit{ it x; it y; public Poit(it x, it y) { this.x = x; this.y = y; Set<Poit> poits = ew HashSet<>(); Poit p1 = ew Poit(1,2); Poit p2 = ew Poit(1,2); poits.add(p1); poits.add(p2); System.out.pritl(poits.size()); Output: 2 ת ו כ נ ה 1 בשפת Java 4
HashSet?HashSet א י ך עובדת הכנסה ל Poit: 9,3? 0 1 2 3 4 5 5 Poit: 1,4 Poit: 9,3 Poit: 3,0 Poit: 2,5 Poit: 3,9 Poit: 5,2 ת ו כ נ ה 1 בשפת Java 5
HashSet? HashSet א י ך עובדת הכנסה ל Poit: 9,3 hashcode 0 1 2 3 4 5 5 Poit: 1,4 Poit: 9,3 Poit: 3,0 Poit: 2,5 Poit: 3,9 Poit: 5,2 ת ו כ נ ה 1 בשפת Java 6
HashSet?HashSet א י ך עובדת הכנסה ל equals Poit: 9,3 0 1 2 3 4 5 5 Poit: 1,4 Poit: 9,3 Poit: 3,0 Poit: 2,5 Poit: 3,9 Poit: 5,2 ת ו כ נ ה 1 בשפת Java 7
HashSet דרישות מהמימוש של :hashcode עבור אותו האובייקט, hashcode צ ר י כ ה להחזיר את אותו הערך ב כ ל ק ר י א ה. אם שני אובייקטים x ו y מקיימים x.equals(y), הפונקציה hashcode צ ר י כ ה להחזיר את אותו הערך עבור שניהם כ ד א י ל י י צ ר ערכים שונים עבור אובייקטים x ו y שאינם מ ק י י מ י ם x.equals(y) ע ל מ נ ת ל ש פ ר ב י צ ו ע י ם. י י צ ו ר ע ר כ י ם ז ה י ם י פ ג ע ר ק ב ב י צ ו ע י ם, ל א ב נ כ ו נ ו ת. ת ו כ נ ה 1 בשפת Java 8
HashSet כ ד א י ל ת ת ל eclipse ל ח ו ל ל ל ב ד א ת ה מ י מ ו ש ש ל.equals ב י ח ד ע ם ה מ י מ ו ש ש ל, hashcode צ ר י ך לוודא שמעדכנים את שני המימושים כ א ש ר י ש ש י נ ו י ב א ו ב י י ק ט י ם ) למשל, מתווספים או מוסרים ש ד ו ת (. HashMap ע ו ב ד ב ד י ו ק באותו האופן. ת ו כ נ ה 1 בשפת Java 9
TreeSet Set<Poit> poits = ew TreeSet<>( (a,b)->iteger.compare(a.x, b.x)); Poit p1 = ew Poit(1,2); Poit p2 = ew Poit(1,2); poits.add(p1); poits.add(p2); System.out.pritl(poits.size()); Output: 1 ח י י ב י ם ל ש ל ו ח Comparator Poit אינה Comparable כ י ו ו ן ש ת ו כ נ ה 1 בשפת Java 10
TreeSet Set<Poit> poits = ew TreeSet<>( (a,b)->iteger.compare(a.x, b.x)); Poit p1 = ew Poit(1,2); Poit p2 = ew Poit(1,2); Poit p3 = ew Poit(1,3); poits.add(p1); poits.add(p2); poits.add(p3); System.out.pritl(poits.size()); Output: 1 ת ו כ נ ה 1 בשפת Java 11
ז ה ק צ ת מ פ ת י ע (.( ה ג י ו נ י,( תלוי אם( TreeSet hashcode אינו ע ו ב ד עם TreeSet ז ה י ש ( HashSet. equals אינו ע ו ב ד ע ם TreeSet של המימוש compare/compareto האלמנטים הם Comparable או שמשתמשים.equals ב) ח י י ל ה י ו ת ע ק ב י ע ם Comparator ב ש ב י ל ב א ח ר ת נ ו כ ל לגלות ששני אובייקטים שאינם equals נ ח ש ב י ם כ ז ה י ם ע " י ה.TreeSet ת ו כ נ ה 1 בשפת Java 12
Geerics ד ו ע ל ע
ע ו ש י ם מ ה ל ל א מ ח ל ק ו ת ג נ ר י ו ת אחת הדוגמאות השכיחות ל ש י מ ו ש בהמרת טיפוסים ב Java היא השימוש ב מ ב נ י נ ת ו נ י ם לפני 1.5 Java מכיוון שעד ל ג ר ס ה 1.5 ל א ניתן היה ל ה ש ת מ ש ב ט י פ ו ס י ם מ ו כ ל ל י ם geerics) (, נ א ל צ ו כותבי הספריות להניח שהאברים הם מהמחלקה הכללית ב י ו ת ר, כ ל ו מ ר Object נ נ י ח כ י ר ו צ י ם לכתוב מנשק ו / או מחלקה עבור מחסנית, ש ת א פ ש ר ליצור מחסנית של שלמים, מחסנית של מחרוזות, ל ל א ש י מ ו ש ב Geerics ו כ ו ' בדוגמא מנשק ל מ ח ס נ י ת, ומחלקה מממשת (ללא החוזה ( 14
מ נ ש ק מ ח ס נ י ת iterface Stack { public Object top (); public void push(object t); public void pop(); public boolea empty(); public boolea full(); 15
מ י מ ו ש מ ח ס נ י ת פ ש ו ט public class FixedCapacityStack implemets Stack{ private Object [] cotet; private it capacity; private it topidex; public FixedCapacityStack(it capacity){ cotet = ew Object[capacity]; this.capacity = capacity; topidex = -1; public Object top () { retur cotet[topidex]; 16
מ י מ ו ש מ ח ס נ י ת פ ש ו ט public void push(object t) { cotet[++topidex] = t; public void pop() { topidex--; public boolea empty() { retur (topidex < 0); public boolea full() { retur (topidex >= capacity - 1) ; 17
נ ש ת מ ש א י ך ב מ ח ס נ י ת? נניח שרוצים מחסנית של מחרוזות : Stack s = ew FixedCapacityStack(5); s.push("hello"); Strig t1 = s.top(); // compilatio error Strig t2 = (Strig) s.top(); //ok ב א ח ר י ו ת המתכנתת לוודא שכל האברים המוכנסים ט י פ ו ס ) כאן מחרוזות (, אחרת ה Castig י י כ ש ל. למחסנית הם מאותו Stack s = ew FixedCapacityStack(5); s.push("hello"); s.push(ew Iteger(4)); s.push(ew PolarPoit(3,2)); Strig t2 = (Strig) s.top(); //compilatio ok. Rutime Error! 18
ב ט י ח ו ת ט י פ ו ס י ם מכיוון שבדיקת ההמרה בטיחות טיפוסים ב ז מ ן נ ע ש י ת ריצה אנחנו מאבדים ז ה ו דבר שאינו רצוי אנו מעוניינים ה נ י ת ן לזמן קומפילציה ל ה ע ב י ר כ כ ל ר ב ו ת ב ד י ק ו ת מ ד ו ע? שכפול פתרון אחר : מנשק / מחלקה ק ו ד! נ פ ר ד ת לכל טיפוס איבר הוספת הטיפוסים המוכללים לשפה פותרת ג ם א ת ב ע י י ת בטיחות הטיפוסים ו ג ם א ת ב ע י י ת ש כ פ ו ל ה ק ו ד 19
מ ח ל ק ה מ ו כ ל ל ת ) ג נ ר י ת ( מנגנון ההכללה מיועד לאפשר שימוש חוזר הטיפוס הסטאטי של ע צ ם ב ל י ב ק ו ד לאבד מידע ל ג ב י בלי הכללה, שימוש חוזר בקוד מתבצע ע ל ידי השמת התייחסות מטיפוס א ח ד לטיפוס אחר, י ו ת ר כללי ; מאותו רגע אין ד ר ך לשחזר את הטיפוס הסטאטי המקורי בלי המרה תפקיד ההכללה הוא צ ו ר ך ל מ נ ו ע בהמרות, שנבדקות מאוחר אבל העניינים מסתבכים ה ה ו ר ש ה ) יחס ה- is-a ) בגלל האינטראקציה בין מנגנון ההכללה י ח ס ו ב י ן ק ו ש י נוסף : תאימות ג ר ס א ו ת ב י ן ג נ ר י ו ת ו ל א ג נ ר י ו ת 20
ע ו ב ד? ז ה א י ך הקומפיילר ממפה את כל המחלקות המוכללות FCStack<Somethig> למחלקה אחת ר ג י ל ה ) לא מוכללת ( שהיא ב ע צ ם FCStack<Object> בקוד שמשתמש במחלקה מוכללת, הקומפיילר מוסיף לקוד המרות מ נ ת לבצע השמות מ- Object לטיפוס הספיציפי, ל מ ש ל Strig ע ל הקומפיילר מוודא שההמרה תמיד תצליח ו ל ע ו ל ם לא תודיע ע ל :ClassCastError Strig t = (Strig) s.top(); כלומר, הטיפוס המוכלל (T ( נ מ ח ק מהקוד שהקומפיילר מייצר ; הוא שימושי ר ק לבדיקות תקינות טיפוסים בזמן קומפילציה ; התהליך נקרא מחיקה (erasure) 21
ב ט י ח ו ת ט י פ ו ס י ם þ ý þ Stack <Strig> ss = ew FCStack <Strig> (5); ss.push("the letter A"); ss.push(ew Iteger(3)); Strig t = ss.top(); // same as:(strig)ss.top(); מכיוון שרק מחרוזות י כ ו ל ו ת להיות מוכלות במחסנית אין ב ה מ ר ה צ ו ר ך ע ו ד Stack <Rectagle> sr = ew FCStack <Rectagle>(5); Rectagle rr = ew Rectagle(...) Rectagle rc = ew ColoredRectagle(...) ColoredRectagle cc = ew ColoredRectagle(...) þ þþ sr.push(rr); sr.push(rc); sr.push(cc); 22
ה כ ל ל ה ו י ח ס is-a ý? þ ý þ Stack <Strig> ts = ew FCStack <Strig> (5); Stack <Object> to = ew FCStack <Object> (5); to = ts; ts.push("the letter A"); ts.push(ew Iteger(3)); to.push(ew Iteger(3)); מסקנה : FCStack<Strig> אינו סוג של FCStack<Object> ז ה לא אינטואיטיבי אבל נ כ ו ן. 23
י ח ס is-a ב מ ע ר כ י ם האם מתקיים י ח ס is-a בין מערך של מחרוזות למערך של אובייקטים? Strig [] strarr = ew Strig[5]; Object [] objarr = strarr; ה ש מ ה זו חוקית מבחינה תחבירית ב ל ב ד. objarr מ צ ב י ע למערך של מ ח ר ו ז ו ת, ולכן שימוש שגוי ב ו י ג ר ו ם ל ש ג י א ת ז מ ן ר י צ ה. objarr[0] = ew Iteger(); // throws ArrayStoreExceptio ההשמה הבאה ג ם ה י א מ ת ק מ פ ל ת, א ך ג ו ר מ ת ר י צ ה : ז מ ן ל ש ג י א ת Object[] objarry = ew Object[1]; Strig[] strarr = (Strig[]) objarry; // throws ClassCastExceptio Java ה ש י מ ו ש בטיפוסים מוכללים סותם פ ר צ ה ז ו בתחביר המקורי של שפת ומונעת מקרים כ א ל ה כ ב ר בשלב הקומפילציה. ת ו כ נ ה 1 בשפת Java 24
מ ע ר כ י ם מ ו כ ל ל י ם ל א ר י צ ה : Java מאפשרת ל נ ו להגדיר מערך עם טיפוס גנרי, אבל מ א פ ש ר לייצר מערך כ ז ה, בגלל מחיקת הטיפוסים ב ז מ ן public class Test<T>{ T[] arr; þ ý public Test(){ arr = ew T[10]; טיפוסים מוכללים " לא מסתדרים " עם מערכים ב. Java ב ד " כ מ ו מ ל ץ להימנע משימוש במערכים מוכללים, ו ל ע ב ו ד עם אוספים מ ו כ ל ל י ם ב מ ק ו ם ז א ת. ת ו כ נ ה 1 בשפת Java 25
ט י פ ו ס י ם types) (raw נ א י ם מנגנון ההכללה נ ו ס ף לג ' אווה מאוחר, ולכן היה צ ו ר ך ב מ ח ל ק ו ת פ ר מ ט ר י ו ת גם מקוד ישן שאין בו הכללות לאפשר שימוש class FCStack <T> implemets Stack <T> {... Stack <Strig> vs = ew FCStack <Strig>(); Stack raw = ew FCStack(); //What about T? raw = vs; vs = raw; // ok //"uckecked" compiler warig ב ש י מ ו ש (Object נ א, ב ט י פ ו ס פרמטר הטיפוס מוחלף ב " גבול העליון " כ ל ל ) ב ד ר ך 26
ה ג ב ו ל ה ו א ה ש מ י י ם ג ב ו ל ע ל י ו ן ה ו א ש ם ש ל ה מ ח ל ק ה א ו ה מ נ ש ק ש מ מ נ ה יורש הטיפוס הפרמטרי כאשר הגבול העליון הוא Object ל א נ י ת ן ל ב צ ע כ ל פ ע ו ל ה ע ל ע צ מ י ם מהטיפוס הגנרי ע ל כ ן, בהגדרת טיפוס ג נ ר י נ י ת ן ל ס פ ק ג ב ו ל עליון אחר הדבר מאפשר ג ב ו ל ע ל י ו ן ל ל א ל ה ש ת מ ש בגוף המחלקה הגנרית צ ו ר ך ב ה מ ר ה בשירותים המוגדרים ב א ו ת ו public class SortedSetImplemetatio<T exteds Comparable> { T elem1 = T elem2 = elem1.compareto( elem2)... expectcomparable(elem1); //elem1 is ideed Comparable 27
Comparable ג נ ר י ש י מ ו ש ב Comparable ש ה ו א raw ה ו א ב ע י י ת י Comparable א ב ל ה ם א י נ ם Comparable יתכנו שני ע צ מ י ם ש כ ל א ח ד מ ה ם ז ה ל ז ה, ל מ ש ל : Strig ו- Iteger א נ ח נ ו נעדיף את הגירסה הגנרית : public class MyClass implemets Comparable{ public it compareto(object other) {... public class MyClass implemets Comparable<MyClass> { public it compareto(myclass other) {... ב צ ו ר ה זאת מגדירים מחלקה שעצמיה ברי השוואה ל ע צ מ ם, ומספקים שרות שמבצע את ההשוואה א ם רוצים אפשרות השוואה ל מ ח ל ק ה כ ל ל י ת י ו ת ר, ז ה נ ע ש ה יותר מסובך ) ל א נ ע ס ו ק ב ז ה ב ק ו ר ס ( 28
ע ל ה מ ר ו ת ש ל, מ ו ז ר ו י ו ת בגלל שבג ' אווה הכללה ממומשת ז כ ר לפרמטר הטיפוס ב א מ צ ע ו ת מנגנון המחיקה, ריצה אין ב ז מ ן כ ל ו מ ר, ב ז מ ן ר י צ ה א י א פ ש ר ל ה ב ח י ן ב י ן עצם מטיפוס, FCStack<Iteger> ו ב י ן עצם מטיפוס FCStack<Strig> ו ב פ ר ט, ב ז מ ן ר י צ ה נראה ששניהם מאותה מחלקה זה משפיע ע ל בדיקת שייכות ל מ ח ל ק ה istaceof) ( עצמים מוכללים, ועל שדות המסומנים static וזה מונע אפשרות ל ק ר ו א ל ב נ א י ע ל פי פרמטר טיפוס, כ ל ו מ ר : <T> void m(t x) { T y = ew T();... // illegal ו י ש ע ו ד ה ר ב ה מ ז ה... 29
ל מ ש ל... ר צ י נ ו ל ש ל ב א ת ה ק ו ד ה ב א ) ש מ צ א נ ו ב ג ר ס ה ישנה של המוצר ( ב מ ו צ ר ה ח ד ש : public static void pritlist(list list) { for(it i=0, =list.size(); i < ; i++) { if (i % 2 == 0) { System.out.pritl(list.get(i)); כ ד י להימנע מאזהרות ק ו מ פ י ל צ י ה נשנה את List לטיפוס מוכלל : public static void pritlist(list<object> list) { for(it i=0, =list.size(); i < ; i++) { if (i % 2 == 0) { System.out.pritl(list.get(i)); לא טוב, ל א נ י ת ן ל ה ע ב י ר ל ש ר ו ת List<Strig> 30
ג ' ו ק ר י ם נ ש ת מ ש ב ג ' ו ק ר ) סימן שאלה -? ( public static void pritlist(list<?> list) { for(it i=0, =list.size(); i < ; i++) { if (i % 2 == 0) { Object obj = list.get(i); System.out.pritl(obj); 31
ג ' ו ק ר י ם כדי שנוכל לבצע פעולות על אברי הרשימה ל ס פ ק חסם י ש ב ש ר ו ת : כ מ ו ע ל י ו ן, public static double sumperimiters(list<? exteds IShape> list) { double total = 0.0; for(ishape : list) total +=.perimeter(); retur total;, IShape הוא טיפוס המרחיב את list משמעות ההגדרה : הטיפוס הגנרי של כולל IShape ע צ מ ו כ מ ו ב ן. ש י מ ו ל ב ל ש י מ ו ש ב exteds ג ם עבור מנשקים. זהו תחביר מיוחד ל ה ר ח ב ו ת. List<IShape> shapes =... ש י מ ו ש ב ש י ר ו ת : List<Circle> circles =... List<Triagle> triagles =... double shapesperimetersum = sumperimiters(shapes); double circlesperimetersum = sumperimiters(circles); double triaglesperimetersum =sumperimiters(triagles); 32
ג ' ו ק ר י ם י ש גם חסמים תחתונים : public static boolea additem(list<? super ColoredRectagle> lst, ColoredRectagle item) { retur lst.add(item); המשמעות : הטיפוס הגנרי של הרשימה list הוא ColoredRectagle או טיפוס שאותו ColoredRectagle מרחיב. List<ColoredRectagle> crectagles=...; List<Rectagle> rectagles=...; List<Object> objects=...; ColoredRectagle crect=...; additem(crectagles, crect); additem(rectagles, crect); additem(objects, crect); ש י מ ו ש ב ש י ר ו ת : 33
super vs. exteds List<T super MyClass> MyClass List<T exteds MyClass> ת ו כ נ ה 1 בשפת Java 34
ש י ר ו ת י ם מ ו כ ל ל י ם 35 נ י ת ן להגדיר טיפוס ל מ ח ל ק ה. ה ש י ר ו ת getfirstitem מכיל פ ר מ ט ר גנרי <T>. ג נ ר י עבור שירות ת ו כ נ ה 1 בשפת Java ר ק ו ל א ב ו ד ד, public class Test{ public static void mai(strig[] args){ List<Iteger> itlst = Arrays.asList(1,2,3); List<Strig> strlst = Arrays.asList("a", "b", "c"); it firstit = getfirstitem(itlst); Strig firststr = getfirstitem(strlst); ערכו של הפרמטר הגנרי י ק ב ע בזמן הקריאה ל ש י ר ו ת. ל מ ש ל, כ א ש ר נ ש ל ח List<Strig> /* כ פ ר מ ט ר, ערכו של T י ק ב ע ל * @pre list.size() > 0.Strig */ public static <T> T getfirstitem(list<t> list){ retur list.get(0);
ו ב ה ק ש ר ש ל מ ח ל ק ו ת פ נ י מ י ו ת... public class MyType<E>{ class Ier{ static class Nested{ public static void mai(strig[] args) { MyType mt; //warig: MyType is a raw type MyType.Ier i; //warig: MyType.Ier is a raw type MyType.Nested est; //o warig, ot a parametrized type MyType<Object> mt1; //o warig MyType<?> mt2; //o warig,? is OK for a type ת ו כ נ ה 1 בשפת Java 36
ל מ ה ט ו ב ש ה ק ו מ פ י י ל ר ש ו מ ר? List ames = ew ArrayList(); //warig: raw type ames.add("kyle"); ames.add("eric"); ames.add(boolea.false); for (Object o : ames){ Strig s = (Strig)o; גילוי השגיאה System.out.pritl(s.toUpperCase()); ב ז מ ן ק ו מ פ י ל צ י ה ו ל א ב ז מ ן ר י צ ה! //throws ClassCastExceptio // java.lag.boolea caot be cast to java.lag.strig List<Strig> ames = ew ArrayList<>(); ames.add("kyle"); ames.add("eric"); ames.add(boolea.false); //compilatio error! ת ו כ נ ה 1 בשפת Java 37
<Object> ש ו נ ה מ Raw public static void mai(strig[] args){ List<Strig> strlst = ew ArrayList<>(); appednewobject(strlst); //compilatio error! public static void appednewobject(list<object> lst){ lst.add(ew Object()); מ ה ה י ה קורה אם הפונקציה appednewobject היתה מ ק ב ל ת List נ א? ת ו כ נ ה 1 בשפת Java 38
(wildcard) Raw ש ו נ ה מ >? < public static void mai(strig[] args){ List<Strig> strlst = ew ArrayList<>(); appednewobject(strlst); //this is fie public static void appednewobject(list<?> lst){ lst.add(ew Object()); //compilatio error! כמובן שזה לא הגיוני שיהיה נ י ת ן ל ה ו ס י ף עצם מטיפוס Object ל ר ש י מ ה של מחרוזות, ל כ ן, צ ר י ך למנוע את ז ה כ ב ר בשלב הקומפילציה. ת ו כ נ ה 1 בשפת Java 39
כ מ ח ל ק ת >? < ב ס י ס public static void pritcollectio(collectio<?> c){ for (Object o: c){ System.out.pritl(o); c נ י ת ן ל ש ל ו ח ל פ ו נ ק צ י ה pritcollectio כל אוסף. ב ת ו ך pritcollectio נ י ת ן ל ג ש ת לאלמנטים מתוך ו ל ש י י ך להם את הטיפוס הסטטי.Object Collectio<?> c = ew ArrayList<>(); c.add(ew Object()); // Compile time error ת ו כ נ ה 1 בשפת Java 40
ס י כ ו ם geerics מנגנון ההכללה מאפשר להימנע מהמרות ב ל י לשכפל קוד קוד שאין בו המרות מפורשות ו ש א י ן בו טיפוסים נ א י ם ) ל י ת ר דיוק, אם ה ק ו מ פ י י ל ר לא הזהיר לגבי השימוש ב ט י פ ו ס י ם נאים ( הוא בטוח מבחינת ט י פ ו ס י ם safe) (type ק ו ד כ ז ה ל א י כ ש ל בביצוע המרה ב ז מ ן ריצה : הבדיקות מועברות ל ז מ ן ה ק ו מ פ י ל צ י ה ה ש י מ ו ש בהכללה מסבך הצהרות על טיפוסים בגלל האינטראקציה הלא א י נ ט ו א י ט י ב י ת בין טיפוסים מוכללים ו ב י ן יחס ה- is-a המימוש של הכללות ב ג ' א ו ו ה כולל מספר מוזרויות ) ו ע ו ד ל א ד י ב ר נ ו ע ל כ ו ל ן... ( דיון מקיף ) מ ע נ י י ן, ו ב ר ו ר ( ב נ ו ש א נ י ת ן ל מ צ ו א בפרק 4.1 של : Java i a Nutshell, 5th Editio By David Flaaga 41
ה ע מ ס ה ו ה ו ר ש ה ת ו כ נ ה 1 בשפת 42 Java
ה ע מ ס ה ו ה ו ר ש ה במקרים של העמסה הקומפיילר מחליט איזו גרסה תרוץ ) י ו ת ר נכון : איזו ג ר ס ה לא תרוץ ( ) הפרוצדורות מתוך ( java.lag.strig : static Strig valueof(double d) { static Strig valueof(boolea b) { נראה סביר ז ה overloaded(rectagle x) { overloaded(coloredrectagle x) { ז ה? ע ם א ב ל מ ה ל א נורא, הקומפיילר ל ה ח ל י ט, י כ ו ל Rectagle r = ew ColoredRectagle (); ColoredRectagle cr = ew ColoredRectagle (); overloaded(r); // we must use the more geeral method overloaded(cr); // The more specific method applies 43
א ב ל ש ל א י ז ה) ה ע מ ס ה ו ה ו ר ש ה ז ה א ב ל כבר מוגזם : overthetop(rectagle x, ColoredRectagle y) { overthetop(coloredrectagle x, Rectagle y) { ColoredRectagle a = ew ColoredRectagle (); ColoredRectagle b = ew ColoredRectagle (); overthetop(a, b); b? א ו a ברור שנדרשת המרה castig) א י ן ד ר ך להחליט ; הפעלת השגרה לא חוקית פ ר מ ט ר? ב ג ' א ו ו ה 44
ה ע מ ס ה ו ה ו ר ש ה - ש ב ר י ר י ו ת overthetop(rectagle x, ColoredRectagle y) { overthetop(coloredrectagle x, Rectagle y) { ColoredRectagle a = ew ColoredRectagle (); ColoredRectagle b = ew ColoredRectagle (); overthetop(a, b); אם הייתה רק הגרסה הירוקה, הקריאה לשגרה הייתה חוקית כאשר מוסיפים את הגרסה הסגולה, הקריאה נ ה פ כ ת ללא חוקית ; אבל ה ק ו מ פ י י ל ר ל א יגלה את ז ה א ם ז ה בקובץ אחר, והתוכנית תמשיך ל ע ב ו ד, לגרסה הירוקה ו ל ק ר ו א לא טוב שקומפילציה זה מצב שברירי ר ק ש ל ק ו ב ץ ש ל א ה ש ת נ ה ת ש נ ה א ת ה ת נ ה ג ו ת ה ת ו כ נ י ת ; 45
ה ע מ ס ה ו ה ו ר ש ה - ש ב ר י ר י ו ת א ם נוציא את הקוד ב A מ ה ה ע ר ה ו נ ק מ פ ל ר ק א ת C, A ת מ ש י ך ל ר ו ץ ע ם ה ג י ר ס א ש ל.B ת ו כ נ ה 1 בשפת Java 46
ה ע מ ס ה - ו ה ו ר ש ה ג ר ו ע י ו ת ר class B { overloaded(rectagle x) { class S exteds B { overloaded(rectagle x) { // override overloaded(coloredrectagle x) { // overload but o override! S o = ew S(); ColoredRectagle cr =... o.overloaded( cr ); // ivoke the purple ((B) o).overloaded( cr ) // What to ivoke? 47
class B { overloaded(rectagle x) { class S exteds B { overloaded(rectagle x) { // override overloaded(coloredrectagle x) { // overload but o override! S o = ew S(); ColoredRectagle cr =... o.overloaded( cr ); // ivoke the purple ((B) o).overloaded( cr ) // What to ivoke? מנגנון ההעמסה הוא סטטי : ב ו ח ר א ת ה ח ת י מ ה ש ל ה ש ר ו ת וסוג הפרמטרים (, א ב ל ע ד י י ן ל א ק ו ב ע איזה שירות י י ק ר א. ) ט י פ ו ס העצם, שם השרות, מספר ע ב ו ר ה ק ר י א ה( (B)) o).overloaded( cr ת י ב ח ר ) ב ז מ ן קומפילציה ( החתימה : B.overloaded(Rectagle) ב ג ל ל ש י ע ד ה ק ר י א ה ה ו א מ ט י פ ו ס B ה ש ר ו ת ה י ח י ד ה ר ל ב נ ט י ה ו א ה א ד ו ם! ב ז מ ן ריצה מופעל מנגנון השיגור הדינמי, שבוחר בין השרותים בעלי חתימה ז א ת, את המתאים ב י ו ת ר, לטיפוס הדינמי של יעד הקריאה. הטיפוס הדינמי הוא, S ל כ ן נבחר השרות הירוק. B b = ew S(); b.overloaded( cr ) 48 כנ " ל אם הקריאה היא :
ר ע ז ה ה ע מ ס ה א ם ע ו ד לא השתכנעתם שהעמסה היא זה הזמן רעיון מסוכן, אז ע כ ש י ו ב י י ח ו ד כאשר ההעמסה היא ז ה, ל א ז ר י ם ל ח ל ו ט י ן ב י ח ס לטיפוסים שמרחיבים ז ה א ת יוצר שבריריות, קוד שמתנהג ב צ ו ר ה לא אינטואיטיבית ) ה ש י ר ו ת שעצם מפעיל תלוי בטיפוס ההתייחסות ל ע צ ם ו ל א ר ק ב מ ח ל ק ה ש ל ה ע צ ם (, ו ק ו ש י לדעת איזה שירות בדיוק מופעל ומכיוון שהתמורה היחידה ) א ם בכלל ( היא אסתטית, כ ד א י ל א 49
ב ח י נ ה ר ה ח ו מ ל ב ח י נ ה כל החומר, כולל תרגולים ו ת ר ג י ל י ב י ת 50 נ ק ע ל ח ל ק פ ת ו ח ו 55 נק שאלות אמריקאיות ב ח י נ ו ת ק ו ד מ ו ת נ י ת ן ל מ צ ו א באתר הקורס פורום שאלות מבחינות קודמות אופן המענה על הבחינה ת ו כ נ ה 1 בשפת Java 50