מתודה וירטואלית (Virtual Method) הנה מתודה אשר מוגדרת וממומשת במחלקת הבסיס, אולם ניתן לספק לה מימושים נוספים בכל אחת מהמחלקות הנגזרות.
נהוג לומר, שהמחלקה הנגזרת יכולה לדרוס/לרמוס (Override) את המימוש הקיים במחלקת הבסיס.
כאשר נפעיל מתודה וירטואלית יופעל המימוש המתאים לטיפוס האובייקט המוקצה ולא לייחוס, במילים אחרות, המימוש יופעל על פי האובייקט המוקצה דינאמית ולא על פי הייחוס המחזיק בכתובת ההקצאה.
הגדרת מתודה וירטואלית מתבצעת באמצעות המילה השמורה virtual, הגדרת מימוש נוסף במחלקה הנגזרת מחייבת שימוש המילה השמורה override.
מתודה וירטואלית אינה יכולה להיות static וכמובן שאינה יכולה להיות private (תסבירו למה?), אבל יכולה להיות Protceted.
תחביר:
1 : classBase
2 : {
3 : ...
4 : publicvirtualvoidFunc()
5 : {
6 : ...
7 : }
8 : }
9 : classDerived:Base
10 : {
11 : ...
12 : publicoverridevoidFunc()
13 : {
14 : ...
15 : }
16 : }
17 : classprogram
18 : {
19 : publicstaticvoidMain()
20 : {
21 : Baseb=newDerived();
22 : b.Func();
23 : }
24 : }
שורה 1: הגדרת מחלקת הבסיס. שורה 4: הגדרת המתודה הוירטואלית באמצעות המילה השמורה virtual מתבצעת תמיד במחלקת הבסיס. שורה 9: הגדרת המחלקה הנגזרת. שורה 12: המחלקה הנגזרת דורסת (Override) את המימוש הקיים במחלקת הבסיס. שורה 21: ייחוס מטיפוס הבסיס Base מקבל מיוחס לאובייקט מהמחלקה הנגזרת Derived. שורה 22: איזה מימוש יופעל? זה של המחלקה הנגזרת.
שורה 5: ייחוס מטיפוס בסיס שמקבל כתובת של אובייקט ממחלקת הבסיס. שורה 6: תופעל המתודה של מחלקת הבסיס.
שורה 8: ייחוס מטיפוס בסיס שמקבל כתובת של אובייקט מהמחלקה הנגזרת. שורה 9: יופעל המימוש המוגדר במחלקה הנגזרת.
במחלקה Person מוגדרת המתודה Print כוירטואלית, המשמעות היא שבכל אחת מהמחלקות הנגזרות, אשר ירשו את המחלקה Person, ניתן לדרוס את המתודה ולספק מימוש אחר.
אם נרצה נוכל להגדיר זאת כאינטרפרטציה שמחלקה מספקת להתנהגות המוגדרת במחלקת הבסיסית.
המחלקה Employee דורסת את המימוש של המתודה Print אשר הוגדרה כוירטואלית במחלקה הבסיסית Person, המחלקה Employee למעשה מספקת מימוש נוסף למתודה וירטואלית זו.
פלט:
כפי שניתן להבחין מהפלט של התוכנית, בקריאה השניה ל-()Print הופעל המימוש השייך למחלקה הנגזרת.
הייחוס p מטיפוס הבסיס עדיין מכיר רק את חברי המחלקה אשר הוגדרו במחלקת הבסיס, ולכן הוא קורא למתודה ()Print המוגדרת במחלקת הבסיס, אולם הפעם יופעל המימוש אשר הוגדר במחלקה Employee.
דהיינו, ניתן לומר שבתוכנית הדוגמה קיימת מתודה אחת ויחידה בשם Print , מתודה זו מוגדרת במחלקת הבסיס Person, המחלקה Employee רק מספקת מימוש נוסף לאותה מתודה של Person , מימוש אשר יופעל כאשר האובייקט המוקצה הנו מ- Employee .
המימוש אשר יופעל בפועל נקבע בזמן ריצה מכיוון שרק בסמוך להפעלת המתודה הוירטואלית ניתן לדעת באיזה אובייקט מדובר (Late Binding).
כללים במימוש מתודות וירטואליות
החתימה של המתודה הוירטואלית המוגדרת במחלקת הבסיס חייבת להיות זהה בכל (שם המתודה, פרמטרים, ערך מוחזר, הרשאת גישה) לחתימה של המימושים הנוספים שלה במחלקה הנגזרת.
ניתן להמשיך ולספק למתודה וירטואלית אשר מוגדרת במחלקת הבסיס מימושים נוספים בשאר המחלקות הנגזרות.
לא ניתן להגדיר מתודות static כוירטואליות. virtual מתייחס להתנהגות של אובייקטים ומחלקות.
לא ניתן להגדיר מתודות private כוירטואליות, משום שלא ניתן יהיה לממשם במחלקה הנגזרת.
לא ניתן להגדיר בצורה מפורשת override כ- virtual למרות שהיא וירטואלית.