תכנות מונחה עצמים (OOP) - פולימורפיזם - מחלקות אבסטרקטיות

סגור באמצעות טופס זה תוכלו לספר ולהמליץ לחבריכם..
שם השולח:
כתובת דוא"ל של השולח:
שם המקבל:
שלח לכתובת דוא"ל:
הוסף הערה:
ככל שמחלקה היא בסיסית יותר היא כללית יותר, המחלקה BaseShape יכולה לייצג עיגולים, מלבנים, מעוינים, משולשים,מתומנים וכו'. לעיתים קרובות אין שום משמעות להקצאת אובייקטים מהמחלקות הבסיסיות ובסיטואציות אחרות הקצאת אובייקט ממחלקת הבסיס יכולה אף להזיק. ניתן למנוע זאת על ידי הגדרת המחלקה כמחלקה אבסטרקטית (Abstract Class). מחלקה אבסטרקטית נועדה לשמש כבסיס לגזירה בלבד, לא ניתן להקצות ממנה אובייקטים, כל ניסיון שכזה יגרור שגיאת קומפילציה.

  מחלקות אבסטרקטיות

 
מאת: ארז קלר


דוגמת קוד​הורדת דוגמאות קוד 
 
כשהייתי תלמיד בתיכון הייתי מאותם התלמידים שהמורים ממש לא אוהבים,
עד היום אני לא יודע מי שמח יותר, המורה כשאני נעדרתי או אני, עבדכם הנאמן, כשהמורה נעדר.
בוקר רענן אחד המורה לספרות שאל אותי האם הכנתי שיעורי בית, עניתי לו שכן, תראה את המחברת הוא דרש במבט מלא ספקות, הוצאתי את מחברת המתמטיקה והראיתי לו בגאווה שהתמודדתי בהצלחה עם כל התרגילים, המורה הביט בי בכעס מבעד למשקפיו העבותות ושאל אותי האם הוא המורה למתמטיקה?
בלית ברירה שלפתי מתיקי את מחברת הספרות שבה השאלות נשארו (כמובן) מיותמות מהתייחסות,
אז מה, מר קלר הצעיר, אתה משקר אותי?,

האם שיקרתי לו?,
האמת היא שלא, לא שיקרתי לו, הוא שאל שאלה כללית ונתן לי האפשרות לבחור את התשובה שנוחה לי.


יש בעיה עם עודף "כלליות" או עם שימוש בביטויים "דו משמעיים", לא רק בעולמנו אנו אלא גם בעולם מונחה העצמים.

מה הבעיה עם יותר מדי כלליות?
שהיא משקפת תמונה חלקית, לא מדוייקת ונתונה לפרשנות.

לדוגמה המשפט הבא: 
"קניתי רהיט" - מה בדיוק קניתי? אולי שולחן, אולי כיסא, אולי מיטה ואולי בכלל מדף?
"קניתי כלי כתיבה" - מה בדיוק קניתי?, אולי עט, אולי עיפרון, ואולי בגלל טוש?
האם קיים אובייקט בשם רהיט?
האם קיים אובייקט בשם כלי תחבורה?
האם קיים אובייקט בשם כלי כתיבה?
האם קיים אובייקט בשם אדם?
האם קיים אובייקט בשם צורה?
האם במציאות היומיומית שלנו מושגים אלו הינם אובייקטים?


האם קיים אובייקט בשם רהיט?, לא!
במציאות היומיומית רהיט אינו אובייקט כי אם סיווג.
שולחן, כסא, ארון, מדף, מיטה וכו' הינם אובייקטים,
המכנה המשותף
של כולם שהם רהיטים.
האם קיים אובייקט בשם כלי תחבורה?, לא!
במציאות היומיומית כלי תחבורה אינו אובייקט כי אם סיווג.
מכונית, מטוס, אופניים, אופנוע וכו' הינם אובייקטים,
המכנה המשותף של כולם שהם כלי תחבורה.
האם קיים אובייקט בשם צורה?, לא!
במציאות היומיומית צורה אינה אובייקט כי אם סיווג.
עיגול, מלבן, משולש, ריבוע הינם אובייקטים,
המכנה המשותף של כולם שהם צורות.

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

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

האם ניתן להביא תכונה זו לידי ביטוי גם לעולם התיכנות מונחה העצמים?

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


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

נניח שניתן לכתוב את שורת הקוד הבאה:
BaseShape b=new BaseShape();
 
איזו צורה הגדרנו?, האם עיגול? האם מלבן?
כשנקרא למתודה Draw מה נצייר? ... לא ברור.
 
ככל שמחלקה היא בסיסית יותר היא כללית יותר,  המחלקה BaseShape יכולה לייצג עיגולים, מלבנים, מעוינים, משולשים,מתומנים וכו'.
לעיתים קרובות אין שום משמעות להקצאת אובייקטים מהמחלקות הבסיסיות ובסיטואציות אחרות הקצאת אובייקט ממחלקת הבסיס יכולה אף להזיק.
ניתן למנוע זאת על ידי הגדרת המחלקה כמחלקה אבסטרקטית (Abstract Class).
מחלקה אבסטרקטית נועדה לשמש כבסיס לגזירה בלבד, לא ניתן להקצות ממנה אובייקטים, כל ניסיון שכזה יגרור שגיאת קומפילציה.
 בכל מקרה שבו מוגדרת מחלקה בסיסית ואין צורך או אין היגיון לאפשר הקצאת אובייקטים ממחלקה זו, נקפיד להגדירה כמופשטת.


מחלקה אבסטרקטית מגדירים בעזרת מילת המפתח  abstract.
abstract class BaseClass
{
    . . .
}

 קוד לדוגמה (AbstarctClass):
 
 1  : abstract class BaseShape 
 2  : { 
 3  :     public int X { get; set; } 
 4  :     public int Y { get; set; } 
 5  :     public Color Color { get; set; } 
 6  : } 
 7  :  
 8  : class Ellipse : BaseShape 
 9  : { 
 10 :     public int Radius { get; set; } 
 11 :  
 12 : } 
 13 : class Rectangle : BaseShape 
 14 : { 
 15 :     public int Width { get; set; } 
 16 :     public int Height { get; set; } 
 17 : } 
 18 :  
 19 : class Program 
 20 : { 
 21 :     static void Main(string[] args) 
 22 :     { 
 23 :         BaseShape shape1 = new Ellipse(); 
 24 :         BaseShape shape2 = new Rectangle(); 
 25 :  
 26 :     } 
 27 : } 
בשורה 1 נגדיר את המחלקה BaseShape כמחלקה אבסטרקטית באמצעות המילה השמורה abstract.
בשורה 8 ובשורה 13 נגדיר מחלקות היורשות את המחלקה האבסטרקטית BaseShape.
בשורות 23 ו- 24 אנו מגדירים ייחוס ממחלקת הבסיס האבסטרקטית אולם מקצים אובייקטים מהמחלקות הנגזרות.
 
 יתרון נוסף של מחלקה אבסטרקטית הוא שניתן להגדיר בה מתודות אבסטרקטיות, אבל זה כבר במאמר הבא.
 


 



כל הזכויות שמורות למחבר ©