אימון מונחה עצמים – קומפילציה, זמן ריצה ופלט

סוג מקרה דוגמה מה בודקים? תוצאה אופיינית הערה לתלמיד
השמת בן לאב A a = new B(); האם B יורשת מ־A? עובר קומפילציה ורץ תקין מותר לשמור אובייקט מסוג בן בתוך משתנה מטיפוס אב.
השמת אב לבן B b = new A(); האם כל A הוא בהכרח B? שגיאת קומפילציה לא כל אובייקט מסוג A הוא גם B. לכן ההשמה אסורה.
Cast מפורש B b = (B)a; האם הקומפיילר מאפשר לבדוק את ההמרה? בדרך כלל עובר קומפילציה אחרי שהקומפילציה עברה, צריך לבדוק בזמן ריצה מהו טיפוס האובייקט שעליו מצביע a.
Cast מצליח A a = new B();
B b = (B)a;
מהו טיפוס האובייקט שעליו מצביע a? רץ תקין המשתנה a מטיפוס A, אבל האובייקט בפועל הוא B. לכן ההמרה מצליחה.
Cast נכשל בזמן ריצה A a = new A();
B b = (B)a;
האם האובייקט שעליו מצביע a הוא באמת B? שגיאת זמן ריצה הקומפיילר מרשה לבדוק, אבל בזמן ריצה מתברר שהאובייקט אינו B.
משתנה מטיפוס Object Object obj = new B(); האם B הוא גם Object? עובר קומפילציה כל אובייקט ב־C# יכול להישמר במשתנה מטיפוס Object.
קריאה לפעולה שלא קיימת בטיפוס המשתנה A a = new B();
a.Bar();
האם Bar קיימת במחלקה A? שגיאת קומפילציה בשלב הקומפילציה מסתכלים על טיפוס המשתנה: A. לא על B.
פעולה רגילה שאינה virtual A a = new B();
a.Foo();
האם Foo מוגדרת כ־virtual? תופעל Foo של A אם הפעולה אינה virtual, הבחירה נעשית לפי טיפוס המשתנה.
פעולה virtual עם override A a = new B();
a.Foo();
האם Foo היא virtual ב־A ו־override ב־B? תופעל Foo של B אם הפעולה virtual, הבחירה נעשית לפי טיפוס האובייקט בפועל.
ToString Console.WriteLine(a); מה מחזירה הפעולה ToString? יודפס הערך שמחזירה ToString כאשר מדפיסים אובייקט, מופעלת עליו ToString.
ToString עם פולימורפיזם A a = new B();
Console.WriteLine(a);
האם B עושה override ל־ToString? אם כן, תופעל ToString של B גם כאן הבחירה לפי טיפוס האובייקט בפועל, כלומר B.
בנאים בירושה B b = new B(); איזה חלק של האובייקט נבנה קודם? קודם בנאי A ואחר כך בנאי B כשיוצרים אובייקט בן, קודם נבנה החלק של האב.
קריאה ל־base בבנאי public B(int x) : base(x) לאיזה בנאי של האב מועבר x? מופעל בנאי האב המתאים base(x) אומר: לפני בנאי B, הפעל את בנאי A עם x.
קריאה ל־base בפעולה base.Foo(); לאיזו גרסה של Foo קוראים? לגרסת האב base.Foo() אומר במפורש: הפעל את Foo של מחלקת האב.
שרשרת ירושה A a = new C(); האם C יורשת מ־B, ו־B יורשת מ־A? תלוי בהיררכיה וב־override צריך לזהות גם את טיפוס המשתנה וגם את טיפוס האובייקט בפועל.
שדות בירושה protected int x; האם למחלקת הבן מותר לגשת לשדה? כן, אם השדה protected protected נגיש למחלקה עצמה וגם למחלקות שיורשות ממנה.

---

נוהל פתרון מומלץ לשאלות קומפילציה, זמן-ריצה ופלט

  1. זהה את טיפוס המשתנה.
  2. זהה את טיפוס האובייקט בפועל.
  3. בדוק האם ההשמה חוקית.
  4. בדוק האם הפעולה קיימת בטיפוס המשתנה.
  5. אם יש Cast – בדוק האם הוא יצליח בזמן ריצה.
  6. אם הפעולה virtual – הבחירה לפי טיפוס האובייקט.
  7. אם הפעולה אינה virtual – הבחירה לפי טיפוס המשתנה.
  8. אם מופיע Console.WriteLine על אובייקט – בדוק ToString().
  9. אם מופיע base – זכור שהוא מפעיל במפורש את גרסת האב.