לאחר מעבר על שאלוני הקוד שב-interactive/ חוזרות כמעט תמיד אותן תחנות החלטה. מי שפותר לפי סדר קבוע לא נופל בקלות במלכודות של override, overload, new, cast, ו-protected.
שלושת החוקים שפותחים כל שאלה
- קודם מזהים את הטיפוס המוצהר של המשתנה שעליו קוראים לפעולה.
- אחר כך מזהים את הטיפוס בזכרון של האובייקט בפועל.
- רק אז מחליטים האם מדובר ב-
overload, ב-override, ב-hiding, ב-cast, או בכלל בשגיאת קומפילציה עוד לפני זמן הריצה.
הטעות הכי נפוצה היא לדלג ישר לטיפוס בזכרון. זה מותר רק אחרי שהקומפיילר כבר מצא חתימה חוקית על פי הטיפוס המוצהר.
הקטגוריות שחוזרות בשאלונים
| קטגוריה | מה צריך לבדוק | מה בדרך כלל קובע את התשובה |
|---|---|---|
| טיפוס מוצהר מול טיפוס בזכרון | מי המשתנה שעליו קוראים לפעולה, ועל איזה אובייקט הוא מצביע בפועל | קומפילציה לפי הטיפוס המוצהר, פולימורפיזם בזמן ריצה לפי הטיפוס בזכרון |
| התאמת חתימה | האם בכלל קיימת פעולה עם אותו שם ועם פרמטרים מתאימים | אם אין חתימה מתאימה, נעצרים עם שגיאת קומפילציה |
overload |
אותו שם פעולה, חתימות שונות | הבחירה נעשית בזמן קומפילציה לפי הטיפוסים המוצהרים של הארגומנטים |
override |
אותה חתימה בדיוק, בשרשרת virtual/override |
אחרי שנבחרה החתימה, ההפעלה נקבעת לפי הטיפוס בזכרון |
hiding עם new |
שם זהה, אבל אין דריסה אלא הסתרה | אין כאן פולימורפיזם דינמי; מה שייקרא תלוי במה שרואים דרך הטיפוס המוצהר |
cast והשמה |
האם ההמרה מותרת תחבירית, והאם האובייקט בפועל מתאים לה | המרה יכולה להתקמפל אבל להיכשל בזמן ריצה עם InvalidCastException |
| הרשאות גישה | private, protected, public |
לעתים השאלה נופלת כבר בקומפילציה כי החבר לא נגיש |
| בנאים וסדר אתחול | מי קורא ל-base(...), מתי משתנים מאותחלים |
חשוב במיוחד כשבנאי של האב קורא לפעולה וירטואלית או כששדות מקבלים ערך דרך שרשרת בנאים |
| שגיאות זמן ריצה נוספות | null, מערכים קו-וריאנטיים, גישה לעצם לא מתאים |
הקוד מתקמפל, אבל נופל רק בזמן הרצה |
סדר פתרון מומלץ בבחינה
- סמנו ליד כל משתנה את הטיפוס המוצהר ואת הטיפוס בזכרון.
- אם יש
cast, בדקו קודם אם הוא חוקי תחבירית, ואז האם הוא באמת יכול להצליח בזמן ריצה. - חפשו רק פעולות שהטיפוס המוצהר מכיר: המחלקה של המשתנה והאבות שלה.
- בחרו חתימה מתאימה. זהו שלב של
overload, ולכן הוא עדיין שלב קומפילציה. - אם הפעולה שנבחרה היא
virtual/override, עברו לטיפוס בזכרון כדי להחליט איזו גרסה תרוץ. - אם הפעולה שנבחרה אינה וירטואלית, או שמדובר ב-
new, הישארו עם הטיפוס המוצהר. - רק בסוף חשבו על הפלט, על ערכי השדות, ועל שגיאות זמן ריצה אפשריות.
צורת רישום
מלכודות קלאסיות מן השאלונים
משפטים שגויים שתלמידים אומרים לעצמם:
- “אם האובייקט בזכרון הוא
Beaver, תמיד תרוץ פעולה שלBeaver”. לא נכון. קודם צריך שהחתימה תיבחר בכלל דרך הטיפוס המוצהר. - “
newזה כמוoverride”. לא נכון.newמסתיר; הוא לא ממשיך את שרשרת הדריסה. - “
castמשנה את האובייקט בזכרון”. לא נכון.castמשנה את מה שהקומפיילר והרץ מתייחסים אליו, אבל לא יוצר אובייקט חדש ולא מחליף טיפוס אמיתי. - “אם יש
override, כבר לא צריך לבדוק חתימה”. לא נכון. בחירת החתימה קודמת לדריסה.
משפט מפתח אחד שכדאי לזכור
overload נבחר לפי טיפוס מוצהר. override נבחר לפי טיפוס בזכרון. new נשאר לפי טיפוס מוצהר. cast נבדק גם בקומפילציה וגם בזמן ריצה.