החלת כמה מיקסינים
חלק מהיחידה תכנות מונחה עצמים במסלול ה-Lua של Coddy. שיעור 52 מתוך 70.
מיקסין יחיד מוסיף למחלקה קבוצה אחת של התנהגויות. אבל אובייקטים אמיתיים זקוקים לעיתים קרובות ליכולות ממקורות מרובים. אובייקט במשחק עשוי להזדקק ליכולת לנוע וגם להיות גלוי על המסך: שני תחומי אחריות נפרדים שלא שייכים לאותו מיקסין.
הפתרון פשוט: החילו כמה mixins על אותה מחלקה. כל 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החל את שני המיקסינים על המחלקה שלך באמצעות אותה פונקציית עזר מקודם:
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 למשחק שמשלבת יכולות מרובות באמצעות mixins! הדמות שלך תוכל גם לתקוף אויבים וגם לרפא את עצמה: שתי התנהגויות נפרדות שמגיעות מ-mixins נפרדים.
תארגן את הקוד שלך בארבעה קבצים:
Attacker.lua: צור mixin עם מתודה:attack(targetName)שמדפיסה{self.name} attacks {targetName} for {self.damage} damage!(בהנחה שלאובייקט יש שדותnameו-damage)Healer.lua: צור mixin עם מתודה:heal(amount)שמוסיפה את הכמות ל-self.healthומדפיסה{self.name} heals for {amount}. Health: {newHealth}Character.lua: צור מחלקת Character עם בנאי:new(name, health, damage)ששומרת את שלוש התכונות. החל גם את ה-mixins של Attacker ושל Healer, כך שכל דמות תוכל לתקוף ולרפא. כלול מתודה:status()שמדפיסה{name} - Health: {health}, Damage: {damage}main.lua: כתוב כאן את פונקציית העזרapplyMixin. קרא קלטים עבור שם הדמות, הבריאות, הנזק, מטרה לתקיפה וכמות לריפוי. צור דמות מסוג Character, הצג את הסטטוס שלה, תן לה לתקוף את המטרה, לרפא את עצמה ואז הצג שוב את הסטטוס שלה.
תקבל חמישה קלטים:
- שם הדמות (מחרוזת)
- בריאות התחלתית (מספר)
- ערך הנזק (מספר)
- שם המטרה לתקיפה (מחרוזת)
- כמות הריפוי (מספר)
הפלט שלך צריך להציג את הדמות משתמשת ביכולות של שני ה-mixins:
{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כל mixin תורם מתודה משלו למחלקת Character. הדמות לא יורשת מאף אחד מה-mixins. היא פשוט מקבלת את היכולות שלהם באמצעות הפונקציה applyMixin. זה הכוח של שילוב כמה mixins!
נסו בעצמכם
-- קובץ ראשי
-- 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 אונליין