משתמש:BDaniel/java

מתוך ויקיפדיה, האנציקלופדיה החופשית

הרצאה 1[עריכת קוד מקור | עריכה]

יחסים בין שתי מחלוקות:

  • איו קשר ביניהן.
  • קשר של הכלה (המחלקה מעגל מכילה אובייקט מהמחלקה נקודה) - has a.
  • קשר הורשה (שעון מעורר יורש משעון. מכונית יורשת מכלי רכב. ריבוע יורש מלבן) - is a.

המחלקה היורשת מקבלת בירושה את כל התכונות והשיטות של מחלקת הבסיס. ניתן להגדיר תכונות נוספות במחלקה היורשת, ניתן להוסיף שיטות חדשות ואפשר להגיד מחדש שיטות קיימות. נניח שבמחלקת הבסיס קיימות 3 תכונות ובמחלקה היורשת הגדרנו 4 תכונות. אז במחלקה היורשת יש 7 תכונות.

  • אם התכונות במחלקת הבסיס מוגדרות כפרטיות (private) אז המחלקה היורשת מקבלת איתן בירושה, אך לא יכולה לגשת אליהן ישירות (הגישה תהיה באמצעות שיטות בלבד).
  • לכן, בדרך כלל נגדיר את תכונות מחלקת הבסיס כ-protected ואז ניתן לגשת אליהן ישירות מהמחלקה היורשת, אך לא ניתן לגשת ממחלוקות אחרות.

מספר מחלוקות יכולות לרשת מחלקת בסיס אחרת. מחלוקה יכולה לרשת ממחלקה אחת בלבד. כדי להגדיר שמחלקה מסוימת יורשת ממחלקה אחרת, נכתוב בכותרת השיטה:

public class (name yoreshet) extands (name basis){ ... }

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

super(param1,param2,param3);

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

הרצאה 2[עריכת קוד מקור | עריכה]

לא היה מה לכתוב.

הרצאה 3[עריכת קוד מקור | עריכה]

public class A{

public void f(){

syso("A");

}

public void g(){

syso("hello");

f();

}

}

public class B extands A{

public void f(){

syso("B");

}

}

אם נכתוב ב-main את:

B myObj = new B();

myObj.g();

אז הפלט יהיה:

hello

B

אם השיטה f היא שיטה סטטית אז הפלט יהיה:

hello

A

Public Vechile[] p = new PublicVechile[5];

כאן, יצרנו מערך בגודל 5 הפניות לכלי רכב ציבוריים. שימו לב שלא נוצר עצם מסוג כלי רכב ציבורי (בהתחלה כל אחת מהפניות נוספת ל-null).

כדי שהקומפיילר יקבל את הפקודה:

‏p[i].show();‏

אז השיטה show חייבת להיות קיימת במחלקה PublicVechile משום שהפניה הוא מסוג זה. אם השיטה show מוגדרת מחדש במחלקה היורשת (אוטובוסים, מוניות ורכבות) אז שכל פעם תופעל השיטה של המחלקה היורשת על פי סוג העצם.

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

הרצאה 4[עריכת קוד מקור | עריכה]

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

if(הפניה instanceof היורשת){

(‏יורשת‏)הפניה.שם שיטה‏(‏);

}

למשל (בדוגמה זו, השיטה p היא שיטה לחישוב שנמצאת במחלקה מלבן, אך לא במחלקה צורה):

if(myShape instanceof Rectangle){

(Rectangle)myShape.p();

}

if(הפניה.getClass() == יורשת.class){

(‏יורשת‏)הפניה.שם שיטה‏(‏);

}

למשל (בדוגמה זו, השיטה p היא שיטה לחישוב שנמצאת במחלקה מלבן, אך לא במחלקה צורה):

if(myShape.getClass() == Rectangle.class){

(Rectangle)myShape.p();

}

ה-getClass משווה למחלקה ספיציפית, ואילו instanceof מסתכל על כל עץ ההורשה.

if(myShape instanceof 2D)

if(myShape.getClass() == 2D.class)

הגדרה מחדש של השיטה equals מהמחלקה object במחלקה A:

public boolean equals(Object o){

if(this == o){

return true;

}

if(o == null){

return false;

}

if(getClass() != obj.getClass()){

return false;

}

A a = (A)obj;

כעת ניתן לפנות לתכונות ולבצע השוואה בין ה-this לפרמטר

}

הרצאה 5[עריכת קוד מקור | עריכה]

אם לעצם שרוצים לשכפל יש רק תכונות מסוג בסיסי מספיק לבצע שכפול רדוד.

  1. בכותרת המחלה נציין שהמחלקה ממשת את הממשק Cloneable:

public class name implements Cloneable { ... }

  1. במחלקה נגדיר מחדש את clone באופן הבא:

public Object clone() throws CloneNotSupportedException {

return super.clone();

}

אם רוצים לשפכל עצן שיש לו לפחות תכונה אחת מחלקתית, יש לבצע שכפול עמוקץ

  1. נציין שהמחלקה ממשת את Cloneable:

public class name implements Cloneable { ... }

  1. נגדיר מחדש במחלקה את clone באופן הבא:
  • נבצע שכפול רדוד
  • לכל תכונה מסוג מחלקתי, נבצע clone בנפרד

public Object clone() throws CloneNotSupportedException {

name temp = (name) super.clone();

if(thona1 instanceof cloneable){

temp.thona1 = (type)thona1.clone();

}

if(thona2 instanceof cloneable){

temp.thona1 = (type) thona2.clone();

}

}

הרצאה 6[עריכת קוד מקור | עריכה]

איטרטורים

מחלקה שמאפשרת לסרוק את איבריה, תממש את הממשק (הקיים ב-java ו-T הוא סוג האיברים הנסרקים):

Iterable <T>

כלומר עליה לממש את השיטה iterator שנמצאת בממשק זה. השיטה iterator מחזירה אובייקט מסוג המחלקה הסורקת (מחלקה שיש לכתוב לצורך הסריקה). בדרך כלל, נרצה להעביר לבנאי של המחלקה הסורקת מידע שיאפשר לו לבצע את הסריקה (אפשר להעביר את העצם אותו רוצים לסרוק - this, או את תכונותיו).

כאמור, כדי לאפשר סריקה, יש להקים סריקה מחלקה חדשה שתהיה המחלקה הסורקת. מחלקה זו דרכה לממש את הממשק (הקיים ב-java ו-T הוא סוג האיברים הנסרקים):

Iterator <T>

כלומר עליה לממש את השיטות:

next

hasNext

remove

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

הרצאה 7[עריכת קוד מקור | עריכה]

פוקציה רקוסיבית היא פונקציה שמפעילה את עצמה לכל פונקציה יהיה תנאי עצירה. ברשימות מקושרות נכתוב במחלקה List שיטה לא רקורסיבית שמפעילה שיטה רקורסיבית על האיבר הראשון. השיטה הרקורסיבית, תהיה כתובה במחלקה ListNode.

בפונקציה רקורססיבית, יהיה בדרך כלל:

  • תנאי עצירה
  • קריאה רקורסיבית (שמבצעת בדרך כלל את המשימה הנדרשת על כל הרשימה פרט לאיבר הראשון)
  • ביצוע המשימה כולל האיבר הראשון.

הרצאה 8[עריכת קוד מקור | עריכה]

ממשק מחלקה מממשת
Set<T> ‏ HashSet<T>
List<T> ‏ Vector<T>
LinkedLIst<T>
Map<K,V> ‏ HashMap<K,V>

הערה: כולם חוץ מ-Map ממשים את Collection ואת Iterable, ולכן ניתן לסרוק כל אוסף פרט למפה.