מתודות מופשטות
חלק מהיחידה תכנות מונחה עצמים במסלול ה-Dart של Coddy. שיעור 44 מתוך 110.
מתודה מופשטת היא מתודה שמוכרזת בתוך מחלקה מופשטת ואין לה גוף. היא מגדירה את חתימת המתודה, אך משאירה את המימוש לכל תת־מחלקה. כל מחלקה שיורשת את המחלקה המופשטת חייבת לדרוס את כל המתודות המופשטות, אחרת גם היא תהיה מופשטת.
abstract class Animal {
// מתודה מופשטת - ללא גוף, תתי-המחלקות חייבות לממש אותה
String makeSound();
// מתודה קונקרטית - יש לה גוף, וכל תתי-המחלקות חולקות אותה
void breathe() {
print('Breathing...');
}
}
class Dog extends Animal {
@override
String makeSound() {
return 'Woof!'; // חובה לספק מימוש
}
}
class Cat extends Animal {
@override
String makeSound() {
return 'Meow!'; // מימוש שונה, אותה חתימה
}
}אם תת־מחלקה תשכח לממש מתודה מופשטת, Dart יציג שגיאת קומפילציה. זו בדיוק המטרה — מתודות מופשטות אוכפות חוזה. מובטח שבכל תת־מחלקה תהיה המתודה הזאת, ולכן אפשר לקרוא לה בבטחה בכל מופע מהטיפוס המופשט.
// אפשר להשתמש בטיפוס המופשט כטיפוס של משתנה
Animal a = Dog();
print(a.makeSound()); // הב הב!
Animal b = Cat();
print(b.makeSound()); // מיאו!מתודות מופשטות שונות ממתודות קונקרטיות במחלקה מופשטת. למתודות קונקרטיות יש גוף והן עוברות בירושה כפי שהן. למתודות מופשטות אין גוף ויש לדרוס אותן.
אפשר לשלב את שניהם באותה מחלקה מופשטת כדי לשתף התנהגויות מסוימות, ובו בזמן לחייב מחלקות משנה להגדיר בעצמן התנהגויות אחרות.
| תכונה | מתודה מופשטת | מתודה קונקרטית |
|---|---|---|
| יש גוף | לא | כן |
| חובה לדרוס | כן | לא |
| מטרה | לאכוף חוזה | לשתף התנהגות |
| היכן | במחלקה מופשטת בלבד | בכל מחלקה |
אתגר
קלבואו נבנה מחשבון צורות שמדגים שיטות מופשטות בפעולה. תגדירו מחלקה מופשטת עם שיטות מופשטות שכל צורה צריכה לממש באופן שונה, ואז תשתמשו בצורות האלה דרך ממשק משותף.
תארגנו את הקוד שלכם בארבעה קבצים:
shape.dart: הגדירו מחלקה מופשטתShapeעם שדהfinalבשםcolor(String) ובנאי שמאתחל אותו. הכריזו על שתי שיטות מופשטות:double area()ו-double perimeter(). הוסיפו גם שיטה קונקרטיתdescribe()שמדפיסהA [color] shape with area: [area] and perimeter: [perimeter]. מכיוון ש-area()ו-perimeter()הן שיטות מופשטות, כל תת-מחלקה תספק חישוב משלה, אבלdescribe()פועלת עבור כולן בלי צורך לדרוס אותה.circle.dart: צרו מחלקהCircleשמרחיבה אתShape. יש לה שדהfinalבשםradius(double). הבנאי שלה מקבל אתcolorואתradiusומעביר אתcolorאלsuper. ממשו אתarea()כך שתחזיר3.14 * radius * radius, ואתperimeter()כך שתחזיר2 * 3.14 * radius.rectangle.dart: צרו מחלקהRectangleשמרחיבה אתShape. יש לה שדותfinalבשםwidthו-height(שניהם double). הבנאי שלה מקבל אתcolor, אתwidthואתheight, ומעביר אתcolorאלsuper. ממשו אתarea()כך שתחזירwidth * height, ואתperimeter()כך שתחזיר2 * (width + height).main.dart: ייבאו את כל הקבצים. צרוCircleעם הצבע'red'ורדיוס5.0, ו-Rectangleעם הצבע'blue', רוחב4.0וגובה6.0. קראו ל-describe()עבור כל צורה. לאחר מכן צרוList<Shape>שמכיל את שתי הצורות, עברו על הרשימה והדפיסוArea: [area]עבור כל צורה.
פלט צפוי:
A red shape with area: 78.5 and perimeter: 31.400000000000002
A blue shape with area: 24.0 and perimeter: 20.0
Area: 78.5
Area: 24.0נסו בעצמכם
import 'shape.dart';
import 'circle.dart';
import 'rectangle.dart';
void main() {
// TODO: צרו Circle עם צבע 'red' ורדיוס 5.0
// TODO: צרו Rectangle עם צבע 'blue', רוחב 4.0 וגובה 6.0
// TODO: קראו ל-describe() על המעגל
// TODO: קראו ל-describe() על המלבן
// TODO: צרו List<Shape> שמכילה את שתי הצורות
// TODO: עברו על הרשימה והדפיסו "Area: [area]" עבור כל צורה
}
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה תכנות מונחה עצמים
1יסודות התכנות מונחה העצמים
קבצים חיצונייםספריות וייבואמבוא לתכנות מונחה עצמיםמחלקות לעומת אובייקטיםמילת המפתח thisמתודותמשתני מופעיסודות הבנאיחזרה: מחשבון פשוט4בטיחות מפני ערכי null
מבוא לבטיחות מפני ערכי nullניתן להקצאה ל-null לעומת לא ניתן להקצאה ל-nullהאופרטורים ? ו-!מילת המפתח Late ובטיחות מפני ערכי nullאופרטורים מודעי nullבטיחות מפני ערכי null במחלקותסיכום – מערכת פרופילי משתמשים7מחלקות מופשטות וממשקים
מחלקות מופשטותמתודות מופשטותממשקים ב-Dartממשקים משתמעיםמימוש לעומת הורשהממשקים מרוביםחזרה – מחשבון צורות10אוספים וגנריות
סקירה כללית של List, Set ו-Mapאוספים בטוחים מבחינת טיפוסיםמחלקות גנריותמתודות גנריותאילוצים גנרייםIterable ו-Iteratorסיכום – אחסון גנרי13מושגי OOP מתקדמים
הרכבה לעומת הורשהמתודות הרחבהמחלקות קריאותמחלקות אטומות (Dart 3)רשומות (Dart 3)תבניות והתאמה (3.0)טיפוסים מונים עם מתודות16פרויקט: ניהול ספרייה
סקירת הפרויקטמחלקות ספר ומשתמש2בנאים ב-Dart
בנאי ברירת מחדלבנאים בעלי שםרשימות אתחולבנאים קבועיםבנאי Factoryבנאים מפניםסיכום - בונה צורות5כימוס
חברים ציבוריים לעומת פרטייםמוסכמת הקידומת _פרטיות ברמת הספרייההעמקה ב-getters וב-settersהסתרת מידעסיכום – רשומות תלמידים8מיקסינים
מבוא למיקסיניםיצירת מיקסיניםשימוש במספר מיקסיניםמילת המפתח on במיקסיניםמיקסינים לעומת ירושהמיקסינים לעומת ממשקסיכום – מערכת בעלי החיים3מאפייני מחלקה
איברי מופע לעומת איברים סטטייםשדות final ו-constמשתני lateמתודות ושדות סטטייםGetters ו-Settersסיכום – מנהל חשבונות בנק6ירושה
ירושה בסיסיתמילת המפתח superדריסת מתודותהאנוטציה @overrideמילת המפתח final למחלקהבנאים וירושהסיכום – היררכיית עובדים9פולימורפיזם
יסודות הפולימורפיזםפולימורפיזם באמצעות ממשקיםבדיקת טיפוסים בזמן ריצההאופרטורים is ו-asמילת המפתח קווריאנטיסיכום — מעבד תשלומים12תכנות מונחה עצמים אסינכרוני
Future-ים ו-async/awaitיסודות ה-Streamsבקרי Streamsבנאים אסינכרונייםאסינכרוניות במתודות של מחלקהסיכום - אחזור נתוניםתרגלו בעצמכם: קומפיילר Dart אונליין