PracticU

מחלקה אבסטרקטית - Abstract Class

בלי כתוביותעם כתוביות
PracticU › קורס תכנות מונחה עצמים - OOP - Object Oriented Programming - חומר לימוד של מדעי המחשב › מחלקה אבסטרקטית - Abstract Class
מילון מושגים:
מחלקה - תבנית בתכנות מונחה עצמים שמגדירה אילו נתונים ופעולות יהיו לאובייקטים שנוצרים ממנה.
פונקציה - קטע קוד בעל שם שמבצע משימה מוגדרת, מקבל ערכי קלט (פרמטרים) ויכול להחזיר תוצאה. מאפשרת לארגן קוד ולהשתמש בו שוב.
אובייקט - יחידה בתכנות מונחה עצמים שמאגדת נתונים (תכונות) ופעולות (מתודות). נוצר בדרך כלל ממחלקה המשמשת כתבנית.
קומפיילר - תוכנה שממירה קוד מקור שנכתב בשפת תכנות לקוד שהמחשב יכול להריץ, ומדווחת על שגיאות תחביר.

מחלקה אבסטרקטית - Abstract Class
השיעור מסביר מחלקה אבסטרקטית (abstract) ופונקציה אבסטרקטית, ולמה יש מחלקות שאין טעם ליצור מהן אובייקט.
למה צריך מחלקה אבסטרקטית
1. בסיס בלבד: Shape משמשת בסיס משותף לעיגולים ולמלבנים, אבל אובייקט Shape לא מתאר צורה אמיתית.
2. אין משמעות לאובייקט: אי אפשר להשלים אובייקט Shape לעיגול או למלבן, ולכן אין סיבה לאפשר ליצור אותו.
3. הגדרה כאבסטרקטית: מוסיפים abstract לפני class. כתיבת new Shape() נכשלת בקומפילציה, אבל רפרנס מטיפוס Shape נשאר חוקי.
פונקציה אבסטרקטית
1. הדרישה: לכל צורה צריכה להיות פונקציה getArea. בעיגול השטח הוא פאי כפול רדיוס בריבוע, ובמלבן רוחב כפול גובה.
2. הבעיה בבסיס: ב-Shape אי אפשר לכתוב נוסחה לשטח, כי לא ידוע איזו צורה זו. החזרת 0 רק משתיקה את הקומפיילר ואינה נכונה.
3. הפתרון: מגדירים את הפונקציה כ-abstract בלי גוף, למשל public abstract double getArea();. פונקציה כזו מופיעה ברפרנס מסוג הבסיס ותמיד וירטואלית.
כללים
1. רק במחלקה אבסטרקטית: פונקציה אבסטרקטית מותרת רק במחלקה שמוגדרת כאבסטרקטית.
2. מימוש חובה: מחלקה לא אבסטרקטית שיורשת מחלקה אבסטרקטית חייבת לממש את כל הפונקציות האבסטרקטיות, אחרת הקומפיילר יציג שגיאה.
3. אפשר לרשת, אי אפשר ליצור: מחלקה אבסטרקטית לא ניתנת להפעלה עם new, אבל ניתן לרשת ממנה וליצור רפרנס מהטיפוס שלה.
שימו לב
לא כל מחלקת בסיס צריכה להיות אבסטרקטית. אבל כשהמחלקה נועדה רק לשמש בסיס, הגדרתה כאבסטרקטית מונעת שימוש לא נכון בה בעתיד. כך אפשר לתכנן עץ הורשה שבו הבסיס מגדיר מה צריך להיות, והמחלקות היורשות ממלאות את הפרטים.
השיעור הבא בקורס: ממשק - Interface בתכנות מונחה עצמים

פרקי ההרצאה: מחלקה אבסטרקטית - Abstract Class

  1. 00:00

    שלושת מרכיבי Object Oriented

  2. 01:38

    הצורך במחלקת SHAPE

  3. 03:36

    SHAPE כישות אבסטרקטית

  4. 06:26

    מחלקת בסיס שאין ליצור ממנה אובייקט

  5. 07:19

    המילה abstract

  6. 10:01

    דרישה לפונקציית שטח פנים

  7. 11:54

    שטח הפנים של מלבן

  8. 14:21

    היעדר GetArea במחלקת הבסיס

תמלול ההרצאה: מחלקה אבסטרקטית - Abstract Class

הטקסט המלא של הדקות הראשונות בהרצאה «מחלקה אבסטרקטית - Abstract Class» בקורס הווידאו של PracticU – כתוביות בעברית עם זמן התחלה לכל פסקה. כך תוכלו לקרוא ולחפש את הנושאים לפני שמתחילים ללמוד.

  1. 00:01

    במהלך הסרטונים של הקורס אנחנו ראינו את שלושת המרכיבים של Object Oriented אנחנו ראינו את ה-Encapsulation, היכולת ליצור מחלקה Inheritance, הורשה, היכולת להעביר את כל ה-Data Members והתכונות והפעילויות של מחלקה למחלקה אחרת

  2. 00:19

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

  3. 00:44

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

  4. 01:08

    מה הכוונה? אפשר להגיד שכל הקונספט של Object Oriented זה להסתכל על העולם האמיתי ולגרום לתוכנה שלנו להיות בדיוק מה שקורה בעולם האמיתי מבחינת אישויות ועצמים וחפצים ואובייקטים וכולי.

  5. 01:25

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

  6. 01:35

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

  7. 02:03

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

  8. 02:30

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

  9. 02:51

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

  10. 03:09

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

  11. 03:28

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

  12. 03:50

    שיהיה לנו יותר קל לעבוד עם שאר הצורות בקוד. אבל זה לא אומר שבמציאות באמת קיים אובייקט שייפ כזה, קיימת ישות שייפ כזאת.

  13. 04:03

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

  14. 04:25

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

  15. 04:57

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

  16. 05:14

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

  17. 05:37

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

  18. 05:59

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

  19. 06:14

    ה-S הזאת שנפתחה כרגע יש בה רק X ו-Y ופרינט ולהביא את המיקום של הצורה מראשית הצירים. אבל איזו צורה באמת זאת? אז אנחנו רואים שאם קיימת לנו מחלקת בסיס שהתפקיד האחד והיחיד שלה זה להוות בסיס למחלקות אחרות, אנחנו לא נרצה ליצור ממנה אובייקט כי אובייקט ממנה יהיה חסר חשיבות

  20. 06:42

    וחסר משמעות בתוכנית. אי אפשר עכשיו לקחת את האובייקט s ופתאום להשלים אותו לסרקל. אובייקט s במקרה הזה הוא שייפ ולא ניתן להשלמה לא לסרקל ולא לרקטנגל.

  21. 06:55

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

  22. 07:14

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

  23. 07:31

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

  24. 07:53

    אז אם אתם בונים את המחלקה שייפ אתם את תכנת א' ואתם יודעים מה הייעוד האמיתי שלה ואתם יודעים שהייעוד האמיתי של שייפ זה להוות בסיס למחלקות צורה אמיתיות ותכנת ב' יכול להשתמש במחלקה שלכם לא להבין את הקונספט הזה

  25. 08:10

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

  26. 08:34

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

  27. 08:49

    הוא לא מתאר לנו שום ישות אמיתית. אם אנחנו עומדים עליו אנחנו רואים cannot create an instance of the abstract class בסדר גמור. לכן בואו נמחוק את זה ונמחוק את זה ונמחוק את זה, נחזיר פה אינדקסים אמיתיים, 0, 1, 2, 3, נגדיר שהמערך הוא בגודל 4 וכעת נבדוק את התוכנית.

  28. 09:18

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

  29. 09:28

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

  30. 09:50

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

  31. 10:18

    כל המחלקות שהן צורות אמיתיות אנחנו רוצים איזושהי פונקציה שתחזיר לנו את שטח הפנים של הצורה הרי אם יש לנו צורה כנראה שיש לה שטח פנים וכמה הצורה תופסת עכשיו, שייפ היא לא באמת צורה אמיתית אוקיי, איך אני יכול לחשב שטח פנים של צורה אם הצורה היא שייפ?

  32. 10:40

    אני לא באמת יכול כי אני לא יודע באמת מה הצורה אבל סרקל היא צורה אמיתית ולכן אנחנו יכולים לכתוב פה את הפונקציה הזו.

  33. 10:52

    בואו נכתוב פונקציה double get area תביא לי את השטח פנים של הצורה. כאן אני צריך להבין איך אני מחשב שטח פנים של עיגול, כלומר מה הנוסחה של חישוב שטח פנים של עיגול.

  34. 11:08

    והנוסחה היא שאנחנו צריכים להחזיר משהו שנקרא Pi R בריבוע. פאי זה קבוע, אנחנו יכולים להשיג אותו בעזרת המחלקה הכללית של .NET Math והוא שווה בערך ל-3.14 ואנחנו רוצים להכפיל אותו ברדיוס ועוד פעם ברדיוס.

  35. 11:35

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

  36. 11:49

    אז כעת יש לנו פונקציה שנקראת getArea פונקציה ואותי מחזירה שטח פנים של הצורה פרקל. אבל הדרישה שקיבלנו זה שכל הצורות יחזיקו פונקציה כזאת.

  37. 12:01

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

  38. 12:23

    רוחב כפול גובה של מלבן ייתן לנו את שטח הפנים של המלבן. יופי. וכעת ענינו על הדרישה.

  39. 12:32

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

  40. 12:48

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

  41. 12:57

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

  42. 13:28

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

  43. 13:49

    בואו נכתוב פה איזושהי פונקציה כללית כזאת static void print areas אנחנו הולכים לקבל shape array אנחנו רוצים לרוץ על כל המערך או ב-foreach או בהילולה רגילה, בואו ננעוץ ב-foreach, לא משנה item in arr ואנחנו רוצים עכשיו להציג את שטח הפנים של הצורה בואו נציג item נקודה

  44. 14:28

    ואין לנו שום פונקציה שנקראת get area למה אין לנו שום פונקציה שנקראת getArea? הרי כרגע כתבנו שתי פונקציות כאלה, אחת בעיגול ואחת במלבן. אז בואו נסתכל רגע ונראה שאייטם הוא מטיפוס shape.

  45. 14:51

    אז זאת הסיבה שאין לנו בעצם פונקציה שנקראת getArea ב-shape, לא קיימת. טוב, אז איך אנחנו יכולים לפתור את הבעיה הזאת?

  46. 15:04

    האם כאשר אנחנו נרוץ בלולאה רגילה על arrayLength ואנחנו ניכנס ל-arr על i הפעם יש לנו get-shape כמובן שלא כי הרי על i זה אובייקט מטיפוס שייפ.

  47. 15:23

    האם אנחנו יכולים לרוץ ב-foreach ולשים circle ואז לגשת ל-get-area?

לקורס המלא: קורס תכנות מונחה עצמים OOP

ההרצאה הקודמת: אופרטורים operators is and as

ההרצאה הבאה: ממשק - Interface בתכנות מונחה עצמים

הרצאות קשורות מקורסים אחרים

  • מחלקה אבסטרקטית ב-NodeJS
  • מחלקה אבסטרקטית ב-TypeScript
  • The R Class
  • יצירת מחלקה עם כל ההגדרות - Config Class - חלק 1

קורסים נוספים במסלול

  • קורס יסודות התכנות - שפת C# .NET - קורס תכנות למתחילים - דוט-נט / סי-שארפ - חומר לימוד של מדעי המחשב