דריסת מתודות
חלק מהיחידה תכנות מונחה עצמים במסלול ה-Lua של Coddy. שיעור 37 מתוך 70.
עד כה, מחלקות יורשות ירשו שיטות ממחלקות האב והוסיפו שיטות חדשות. אבל מה אם מחלקה יורשת זקוקה לאותו שם של שיטה עם התנהגות שונה? זה נקרא דריסת שיטה.
כשמגדירים מתודה במחלקת צאצא בשם זהה לזה של מתודה במחלקת האב, הגרסה של מחלקת הצאצא מקבלת עדיפות. שרשרת החיפוש של Lua בודקת קודם את מחלקת הצאצא, ואם היא מוצאת בה את המתודה, היא מפסיקה לחפש.
local Animal = {}
Animal.__index = Animal
function Animal:new(name)
local obj = {name = name}
setmetatable(obj, Animal)
return obj
end
function Animal:speak()
print(self.name .. " makes a sound")
end
-- Dog דורסת את speak()
local Dog = {}
Dog.__index = Dog
setmetatable(Dog, {__index = Animal})
function Dog:new(name)
local obj = Animal.new(Animal, name)
setmetatable(obj, Dog)
return obj
end
function Dog:speak()
print(self.name .. " barks: Woof!")
endכעת כל מחלקה מגיבה באופן שונה לאותה קריאה למתודה:
local generic = Animal:new("Creature")
local buddy = Dog:new("Buddy")
generic:speak() -- פלט: Creature משמיע קול
buddy:speak() -- פלט: Buddy נובח: Woof!הגרסה של :speak() של Dog מחליפה לחלוטין את הגרסה של מחלקת האב עבור מופעים של Dog. כך אפשר ליצור התנהגות ייחודית תוך שמירה על ממשק עקבי: כל בעל חיים יכול לבצע :speak(), אבל כל מין עושה זאת אחרת.
אתגר
קלבואו נבנה ממלכת חיות קטנה שבה יצורים שונים מדברים בדרכים הייחודיות להם! תיצור מחלקת אב Animal ושתי מחלקות יורשות, Cat ו־Cow, שכל אחת מהן דורסת את המתודה :speak() של מחלקת האב בהתנהגות ייחודית משלה.
תארגן את הקוד שלך בארבעה קבצים:
Animal.lua: מחלקת הבסיס שלך, עם בנאי:new(name)ששומר את שם החיה. הוסף מתודה:speak()שמדפיסה את שם החיה ואחריוmakes a sound. זוהי התנהגות ברירת המחדל שהמחלקות היורשות ידרסו.Cat.lua: מחלקה יורשת מ־Animal. הבנאי:new(name)שלה אמור לקרוא לבנאי של מחלקת האב, ואז לקשר מחדש את מטא־טבלת המתודות ל־Cat. דרוס את המתודה:speak()כך שהחתולים יגידו משהו אחר: הדפס את שם החתול ואחריוmeows: Meow!Cow.lua: מחלקה יורשת נוספת מ־Animal. הגדר את הבנאי באותו אופן כמו ב־Cat. דרוס את:speak()כך שהפרות ידפיסו את שמן ואחריוmoos: Moo!main.lua: חבר את הכול יחד! קרא שני שמות מהקלט, צור Cat עם השם הראשון ו־Cow עם השם השני, ואז קרא ל־:speak()של כל אחת מהן כדי להדגים שאותו שם של מתודה מפיק פלט שונה בהתאם למחלקה.
יתקבלו שני קלטים:
- שם החתול
- שם הפרה
בקובץ הראשי שלך, צור את שתי החיות וקרא ל־:speak() של החתול תחילה, ואז של הפרה.
לדוגמה, אם הקלטים הם Whiskers ו־Bessie, הפלט אמור להיות:
Whiskers meows: Meow!
Bessie moos: Moo!שים לב איך שתי החיות מגיבות לאותה קריאה למתודה :speak(), אבל כל אחת מפיקה פלט שמותאם לסוג שלה. הגרסה של Cat מחליפה לחלוטין את התנהגות ברירת המחדל הכללית של מחלקת האב, "makes a sound", וכך גם הגרסה של Cow. זוהי דריסת מתודות בפעולה: אותו ממשק, מימושים שונים!
נסו בעצמכם
-- main.lua: לחבר את הכול יחד
local Cat = require('Cat')
local Cow = require('Cow')
-- קריאת הקלט
local catName = io.read()
local cowName = io.read()
-- TODO: ליצור Cat עם השם הראשון
-- TODO: ליצור Cow עם השם השני
-- TODO: לקרוא ל־:speak() קודם על החתול, ואז על הפרה
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה תכנות מונחה עצמים
4פרויקט: בנק דיגיטלי
הגדרת הפרויקטפעולת הפקדה7פולימורפיזם ודריסת מתודות
דריסת מתודותקריאה למתודות של מחלקת האבטיפוסיות ברווזממשק משותףבדיקת טיפוססיכום – תפקידי עובדים2תבנית אב־טיפוס למחלקה
מושג אב־הטיפוסקישור באמצעות __indexהבנאי :new()אתחול מאפייניםמופעים עצמאייםסיכום – מפעל מכוניות5העמסת אופרטורים בתכנות מונחה עצמים
חיבור אובייקטיםחיסור אובייקטיםשרשור אובייקטיםהשוואת אובייקטים (<, >)חזרה – חישובים עם ארנק8כימוס
כללי מתן שמותClosures לשמירה על פרטיותגישה באמצעות Closuresטבלאות לקריאה בלבדלוגיקת אימותסיכום – כספת מאובטחת11תבניות עיצוב (בקצרה)
פונקציות Factoryטבלת Singletonתבנית IteratorObserver (מאזין)סיכום – מפעל Logger3מצב והתנהגות של אובייקטים
משתני מופעמתודות Getterמתודות Setterמאפיינים מחושביםעיצוב מחרוזותבדיקות שוויוןסיכום – ציון תלמיד6יסודות הירושה
הכנת מבנה הירושהירושת מתודותהרחבת הבנאיהוספת מתודות למחלקת הבתמשותף לעומת ייחודיסיכום – היררכיית צורותתרגלו בעצמכם: קומפיילר Lua אונליין