החלת כמה מיקסינים
חלק מהיחידה תכנות מונחה עצמים במסלול ה-Lua של Coddy. שיעור 52 מתוך 70.
Mixin יחיד מוסיף קבוצה אחת של התנהגויות למחלקה. אבל אובייקטים אמיתיים זקוקים לעיתים קרובות ליכולות ממקורות מרובים. ייתכן שאובייקט במשחק יצטרך לנוע וגם להיות גלוי על המסך: שתי דאגות נפרדות שלא שייכות לאותו mixin.
הפתרון פשוט: החילו כמה מיקסינים על אותה מחלקה. כל מיקסין תורם את המתודות שלו, ובסופו של דבר למחלקה יש את כולן:
local Movable = {}
function Movable:move(dx, dy)
self.x = self.x + dx
self.y = self.y + dy
end
local Visible = {}
function Visible:show()
print("Showing at " .. self.x .. ", " .. self.y)
end
function Visible:hide()
print("Hidden")
endהחילו את שני ה-mixins על המחלקה שלכם באמצעות אותה פונקציית עזר כמו קודם:
local function applyMixin(class, mixin)
for key, value in pairs(mixin) do
class[key] = value
end
end
local GameObject = {}
GameObject.__index = GameObject
applyMixin(GameObject, Movable)
applyMixin(GameObject, Visible)כעת מופעים של GameObject יכולים גם לנוע וגם להציג את עצמם:
local obj = setmetatable({x = 0, y = 0}, GameObject)
obj:move(5, 3)
obj:show() -- מוצג במיקום 5, 3הערה חשובה: אם שתי ערבובות מגדירות שיטה בעלת אותו שם, הערבובה השנייה שתוחל תדרוס את הראשונה. הקפידו על שמות ייחודיים לשיטות בערבובות שלכם כדי למנוע התנהגות בלתי צפויה.
אתגר
קלבואו נבנה מחלקת Character למשחק, שמשלבת כמה יכולות באמצעות מיקסינים! הדמות שלכם תוכל גם לתקוף אויבים וגם לרפא את עצמה: שתי התנהגויות נפרדות שמגיעות ממיקסינים שונים.
תארגנו את הקוד שלכם בארבעה קבצים:
Attacker.lua: צרו מיקסין עם מתודת:attack(targetName)שמדפיסה{self.name} attacks {targetName} for {self.damage} damage!(בהנחה שלאובייקט יש שדותnameו-damage)Healer.lua: צרו מיקסין עם מתודת:heal(amount)שמוסיפה את הכמות אלself.healthומדפיסה{self.name} heals for {amount}. Health: {newHealth}Character.lua: צרו מחלקת Character עם בנאי:new(name, health, damage)ששומר את כל שלוש התכונות. החילו גם את המיקסין Attacker וגם את המיקסין Healer, כך שכל דמות תוכל לתקוף ולרפא. כללו מתודת:status()שמדפיסה{name} - Health: {health}, Damage: {damage}main.lua: כתבו כאן את פונקציית העזרapplyMixin. קראו קלטים עבור שם הדמות, בריאות, נזק, מטרה לתקיפה וכמות לריפוי. צרו Character, הציגו את המצב שלה, תקפו את המטרה, רפאו את עצמכם ואז הציגו שוב את המצב שלה.
תקבלו חמישה קלטים:
- שם הדמות (מחרוזת)
- בריאות התחלתית (מספר)
- ערך הנזק (מספר)
- שם המטרה לתקיפה (מחרוזת)
- כמות לריפוי (מספר)
הפלט שלכם צריך להראות את הדמות משתמשת בשתי היכולות שמספקים המיקסינים:
{name} - Health: {health}, Damage: {damage}
{name} attacks {target} for {damage} damage!
{name} heals for {healAmount}. Health: {newHealth}
{name} - Health: {newHealth}, Damage: {damage}לדוגמה, אם הקלטים הם Warrior, 100, 25, Goblin ו-30, הפלט צריך להיות:
Warrior - Health: 100, Damage: 25
Warrior attacks Goblin for 25 damage!
Warrior heals for 30. Health: 130
Warrior - Health: 130, Damage: 25כל מיקסין מוסיף מתודה משלו למחלקת Character. הדמות לא יורשת מאף אחד מהמיקסינים. היא פשוט מקבלת את היכולות שלהם באמצעות הפונקציה applyMixin. זהו הכוח שבשילוב כמה מיקסינים!
נסו בעצמכם
-- הקובץ הראשי
-- TODO: כתבו את פונקציית העזר applyMixin
-- פונקציה זו צריכה להעתיק את כל המתודות מטבלת mixin לטבלת היעד
local function applyMixin(target, mixin)
-- TODO: ממשו את החלת ה-mixin
end
-- הנגישו את applyMixin באופן גלובלי כדי ש-Character.lua יוכל להשתמש בה
_G.applyMixin = applyMixin
local Character = require('Character')
-- קראו את הקלטים
local name = io.read()
local health = tonumber(io.read())
local damage = tonumber(io.read())
local targetName = io.read()
local healAmount = tonumber(io.read())
-- TODO: צרו Character עם השם, הבריאות והנזק הנתונים
-- TODO: הציגו את מצב הדמות
-- TODO: גרמו לדמות לתקוף את המטרה
-- TODO: גרמו לדמות לרפא את עצמה
-- TODO: הציגו שוב את מצב הדמות
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה תכנות מונחה עצמים
4פרויקט: בנק דיגיטלי
הגדרת הפרויקטפעולת הפקדה7פולימורפיזם ודריסת מתודות
דריסת מתודותקריאה למתודות של מחלקת האבטיפוסיות ברווזממשק משותףבדיקת טיפוססיכום – תפקידי עובדים2תבנית אב־טיפוס למחלקה
מושג אב־הטיפוסקישור באמצעות __indexהבנאי :new()אתחול מאפייניםמופעים עצמאייםסיכום – מפעל מכוניות5העמסת אופרטורים בתכנות מונחה עצמים
חיבור אובייקטיםחיסור אובייקטיםשרשור אובייקטיםהשוואת אובייקטים (<, >)חזרה – חישובים עם ארנק8כימוס
כללי מתן שמותClosures לשמירה על פרטיותגישה באמצעות Closuresטבלאות לקריאה בלבדלוגיקת אימותסיכום – כספת מאובטחת11תבניות עיצוב (בקצרה)
פונקציות Factoryטבלת Singletonתבנית IteratorObserver (מאזין)סיכום – מפעל Logger3מצב והתנהגות של אובייקטים
משתני מופעמתודות Getterמתודות Setterמאפיינים מחושביםעיצוב מחרוזותבדיקות שוויוןסיכום – ציון תלמיד6יסודות הירושה
הכנת מבנה הירושהירושת מתודותהרחבת הבנאיהוספת מתודות למחלקת הבתמשותף לעומת ייחודיסיכום – היררכיית צורות9קומפוזיציה ומיקסינים
קשר מסוג יש-לוהאצלהמיקסינים פשוטיםהחלת כמה מיקסיניםמיקסינים לעומת ירושהסיכום – הרכבת רובוטתרגלו בעצמכם: קומפיילר Lua אונליין