קישור דינאמי בג'אוה

קישור דינאמי בג'אוה

הבנתי שבג'אוה אין את אותה "בעיה" ב-CPP , ולכן הקישור הדינאמי הוא מה שקורה במערכת כברירת מחדל. אם כך, מדוע עדיין יש צורך ב-casting , לדוגמה כשנרצה לממש שיטה שקיימת רק ביורשים ולא באבא? הרי לשם כך קיים קישור דינאמי, לא ?
 

BravoMan

Active member
שאלה לא מובנת לחלוטין...

קישור דינאמי פירושו שחלק מהקוד לא קיים בתוך התוכנה המקומפלת, אלא במקום אחר במערכת, וכאשר התוכנה רצה המערכת טוענת דינמית ספריה חיצונית לצורך שימוש בה.
&nbsp
casting קשור לדרך בה שפה מתמודדת עם טיפוסים.
&nbsp
לא ממש ברור איזה מקרה אתה מתאר, אבל אם אתה מתכוון למצב בו יש משתנה מסוג "אבא" ואתה רוצה לגשת לפונקציה שיש רק ב-"בן" הרי העניין הוא כזה:
&nbsp
כל משתנה ב-Java שאמור להחזיק אובייקט מחזיק למעשה רפרנס אליו.
ה-casting נחוץ כדי להבהיר שמנסים להשתמש ב-reference כאילו הוא פונה לאובייקט מסוג בן, כי בזמן קומפילציה אי אפשר לדעת איזה רפרפנס יהיה בתוך המשתנה, והקומפיילר לא יכול לנחש אלו פונקציות יהיו זמינות בלי שתבהיר לו זאת.
 
תוכל בבקשה לתת דוגמה למקרה שבו

הקומפיילר לא יכול לנחש אלו פונקציות יהיו זמינות בלי שנבהיר לו זאת?
 

BravoMan

Active member
בכל מקרה בו המשתנה או הפרמטר מקבל את הערך

שלו בזמן ריצה.

נניח שיש לך פונקציה שתפקידה למיין רשימות.
הפונקציה נראית כך:

קוד:
List sort(List original) {
    //do sorting
    return sorted; //sorted copy of the list
}
בשפת Java, הטיפוס List הוא למעשה Interface, ויש הרבה מחלקות שונות שיכולות לממש אותו כגון ArrayList ו-LinkedList ו-Stack.

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

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

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

אם היית צריך להריץ כזה בכל קומפילציה רק כדי לחסוך לעצמך איזה casting, כל קומפילציה היית אורכת הרבה יותר זמן!
 
לראשונה אני קורא על טיפוס כזה...אז ב-JAVA לא צריך לעשות

פולימורפיזם כמו שעושים ב-CPP למשל? כי עד עכשיו לא ראיתי משהו שדומה לזה.
 

BravoMan

Active member
מה זאת אומרת "לא צריך לעשות פולימורפיזם"?

מה שהראיתי לך זה דוגמה לפולימורפיזם.
ב-Java, לממש interface זה כמו לרשת ממחלקה.
&nbsp
ההבדל הוא, שטכנית, אין ירושה מרובה כמו ב-++C, אז אתה יכול לרשת (extends) רק מחלקה אחת, אבל לממש (implements) כמה interfaceים שאתה רוצה.
&nbsp
כמובן, בתוך ה-interface אין קוד*, רק הגדרה של פונקציות, אבל הראיון הכללי הוא כמו בירושה.
&nbsp
* החל מ-Java 9 יש אפשרות להוסיף קוד ל-interface וכך בעצם Java קיבלה ירושה מרובה בדרך לא דרך.
 

BravoMan

Active member
אם אתה רוצה, תן דוגמה למה אתה קורא "פולימורפיזם ב-CPP"

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

BravoMan

Active member
מסביר שוב:

"קישור דינאמי" זה מונח שאין לו שום קשר לפולימורפיזם או casting.
&nbsp
"קישור דינאמי" זה כאשר חלק מהקוד שהתוכנה שלך צריכה לא יושב בתוך הקובץ של התוכנה שלך.
&nbsp
למשל, כאשר אתה משתמש בספרייה שיושבת בתוך DLL, או ב-JAR שאתה מצפה שיהיה בתוך ה-classpath על המערכת.
&nbsp
אני לא יודע למה בדיוק אתה קורא "קישור דינאמי", אבל זה מן הסתם לא זה.
אתה יכול לתת דוגמת קוד?
 
אתם לא מדברים על אותו דבר
השואל המקורי כנראה מתכוון ל dynamic typing, כלומר להתייחסות למשתנה לפי הטיפוס בזמן ריצה שלו ולא הטיפוס בקומפילציה.
&nbsp
ולשואל המקורי: ++C ו JAVA מתנהגות בדיוק אותו דבר בהקשר הזה. איפה שצריך באחת לעשות cast צריך גם בשניה, ולהיפך.
 
פולימורפיזם בסיסי הוא כמעט זהה בין JAVA ל ++C
אז ב ++C כותבים class Derived: public Base
וב JAVA כותבים class Derived extends Base
&nbsp
המשמעות היא זהה, ורוב פרטי המימוש זהים.
יש ניואנסים חשובים, כמו זה שב JAVA כל הפונקציות וירטואליות וב ++C רק אלו שהכרזת עליהן ככאלו מראש, או זה שב JAVA הכל יורש מ Object וב ++C לא, אבל אלו ניואנסים. אני שוב מרגיש שאתה מנסה ללמוד שפה ע״י לימוד בעל פה של אוסף עצום של פרטים קטנים וטפלים ומתעלם לגמרי מהמהות של השפה ומדרך הלימוד הנכונה שלה.
 

selalerer

New member
כשאומרים "קישור דינאמי" מתכוונים בדרך כלל למשהו אחר

נראה שהמושג שאתה מחפש dynamic dispatch שבאמת ב-++C צריך להשתמש במילה virtual בצורה מפורשת בעוד ב-Java זו הברירת מחדל לכל המטודות.
&nbsp
זה לא ממש קשור ל-cast ואין צורך ב-cast בכדי להשתמש ב-dynamic dispatch ב-Java.
&nbsp
אולי אם תראה דוגמא למה שהתכוונת השאלה תהיה ברורה יותר
 
למעלה