האופרטורים is ו-as
חלק מהיחידה תכנות מונחה עצמים במסלול ה-Dart של Coddy. שיעור 60 מתוך 110.
בעוד ש-runtimeType מציין לך את הסוג המדויק, Dart מספקת שני אופרטורים מעשיים יותר לבדיקת סוג ולהמרת טיפוסים: is ו-as.
האופרטור is בודק אם אובייקט הוא מטיפוס מסוים ומחזיר ערך בוליאני. בניגוד ל־runtimeType, הוא מחזיר גם true עבור טיפוסי־אב:
class Animal {}
class Dog extends Animal {}
void main() {
Animal pet = Dog();
print(pet is Dog); // true
print(pet is Animal); // true (Dog הוא Animal)
print(pet is String); // false
}כשמשתמשים ב־is בתוך משפט if, Dart מקדמת אוטומטית את הטיפוס, ומאפשרת לגשת לחברי תת־המחלקה בלי המרה מפורשת:
void handleAnimal(Animal animal) {
if (animal is Dog) {
// Dart יודע שכאן animal הוא Dog
animal.bark(); // אפשר לקרוא למתודות ייחודיות ל-Dog
}
}האופרטור as ממיר אובייקט באופן מפורש לטיפוס מסוים. השתמש בו כשאתה בטוח מהו הטיפוס:
Animal pet = Dog();
Dog myDog = pet as Dog; // בצע המרת טיפוס ל-Dog
myDog.bark();היזהרו בשימוש ב־as — אם ההמרה נכשלת, נזרקת חריגה. לכן שילוב של is עם קידום טיפוסים בטוח לעיתים קרובות יותר משימוש ישיר ב־as. אפשר גם להשתמש ב־is! כדי לבדוק אם אובייקט אינו מטיפוס מסוים.
אתגר
קלבואו נבנה מערכת לעיבוד צורות שמשתמשת באופרטורים is ו-as כדי לזהות ולעבוד עם סוגים שונים של צורות. תיצור היררכיה של צורות ותכתוב פונקציות שבודקות טיפוסים ומאפשרות גישה בטוחה למאפיינים ייחודיים לכל טיפוס.
תארגן את הקוד שלך בשני קבצים:
shapes.dart: הגדר כאן את היררכיית הצורות:- מחלקת
Shapeעם מאפייןString nameובנאי. כלול בה מתודהdescribe()שמדפיסה[name] is a shape - מחלקת
Circleשיורשת מ-Shapeוכוללת מאפיין נוסףdouble radius. הוסף מתודהgetCircleInfo()שמדפיסהCircle with radius: [radius] - מחלקת
Rectangleשיורשת מ-Shapeוכוללת את המאפיינים הנוספיםdouble widthו-double height. הוסף מתודהgetRectangleInfo()שמדפיסהRectangle: [width] x [height]
- מחלקת
main.dart: ייבא את קובץ הצורות שלך וצור פונקציהprocessShape(Shape shape)ש:- קוראת תחילה ל-
describe()של הצורה - משתמשת ב-
isכדי לבדוק אם הצורה היאCircle— אם כן, השתמש בקידום טיפוסים כדי לקרוא ל-getCircleInfo() - משתמשת ב-
isכדי לבדוק אם הצורה היאRectangle— אם כן, השתמש באופרטורasכדי להמיר את הטיפוס שלה וקרא ל-getRectangleInfo() - משתמשת ב-
is!כדי לבדוק אם הצורה אינהCircleוגם אינהRectangle— אם כן, הדפסUnknown shape type
main()שלך:- צור
Circleבשם'Round'עם רדיוס5.0והעבר אותו אלprocessShape() - הדפס שורה ריקה
- צור
Rectangleבשם'Box'עם רוחב4.0וגובה3.0והעבר אותו אלprocessShape() - הדפס שורה ריקה
- צור
Shapeבסיסית בשם'Mystery'והעבר אותה אלprocessShape()
- קוראת תחילה ל-
האתגר הזה מדגים את שתי הגישות: שימוש ב-is עם קידום טיפוסים אוטומטי עבור Circle, ושימוש ב-as להמרת טיפוס מפורשת עבור Rectangle. תראה גם איך is! עוזר לזהות צורות שאינן תואמות לאף תת-טיפוס ספציפי.
פלט צפוי:
Round is a shape
Circle with radius: 5.0
Box is a shape
Rectangle: 4.0 x 3.0
Mystery is a shape
Unknown shape typeנסו בעצמכם
import 'shapes.dart';
// TODO: צרו פונקציה processShape(Shape shape) אשר:
// 1. תחילה קוראת ל־describe() על הצורה
// 2. משתמשת ב־'is' כדי לבדוק אם הצורה היא Circle - אם כן, השתמשו בקידום טיפוסים כדי לקרוא ל־getCircleInfo()
// 3. משתמשת ב־'is' כדי לבדוק אם הצורה היא Rectangle - אם כן, השתמשו באופרטור 'as' להמרת טיפוס ולקריאה ל־getRectangleInfo()
// 4. משתמשת ב־'is!' כדי לבדוק אם הצורה אינה Circle ואינה Rectangle - אם כן, הדפיסו "Unknown shape type"
void main() {
// TODO: צרו Circle בשם 'Round' עם רדיוס 5.0 והעבירו אותו ל־processShape()
// TODO: הדפיסו שורה ריקה
// TODO: צרו Rectangle בשם 'Box' עם רוחב 4.0 וגובה 3.0 והעבירו אותו ל־processShape()
// TODO: הדפיסו שורה ריקה
// TODO: צרו Shape בסיסי בשם 'Mystery' והעבירו אותו ל־processShape()
}
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה תכנות מונחה עצמים
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 אונליין