| השמת בן לאב |
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 נגיש למחלקה עצמה וגם למחלקות שיורשות ממנה. |