Menu
Coddy logo textTech

מאפיינים מחושבים

חלק מהיחידה תכנות מונחה עצמים במסלול ה-Lua של Coddy. שיעור 15 מתוך 70.

פונקציות גישה (getters) ופונקציות עדכון (setters) מאפשרות גישה לערכים שמורים, אבל לפעמים דרושים לך נתונים שאינם קיימים כשדה שמור. צריך לחשב אותם מתוך מאפיינים אחרים. אלה נקראים מאפיינים מחושבים.

חשבו על מלבן. אתם שומרים את הרוחב והגובה שלו, אבל השטח לא נשמר בשום מקום: הוא מחושב על ידי הכפלת שני הערכים האלה זה בזה. במקום לשמור נתונים מיותרים, אתם יוצרים מתודה שמחשבת ומחזירה את התוצאה:

local Rectangle = {}
Rectangle.__index = Rectangle

function Rectangle:new(width, height)
    local instance = {}
    setmetatable(instance, self)
    instance.width = width
    instance.height = height
    return instance
end

function Rectangle:getArea()
    return self.width * self.height
end

המתודה :getArea() לא מחזירה ערך שמור. היא מחשבת את השטח מחדש בכל פעם שקוראים לה. לגישה הזאת יש יתרון מרכזי: אם הרוחב או הגובה משתנים, השטח משקף אוטומטית את המידות החדשות, בלי שתצטרכו לעדכן דבר.

local box = Rectangle:new(5, 3)
print(box:getArea())  -- פלט: 15

box.width = 10
print(box:getArea())  -- פלט: 30

מאפיינים מחושבים שומרים על עקביות האובייקטים שלך. במקום לאחסן ערכים שתלויים בשדות אחרים (ולהסתכן בכך שהם יתיישנו), מחשבים אותם לפי הצורך. התבנית הזו מתאימה לכל נתון נגזר: היקפים, ממוצעים, מחרוזות בפורמט מסוים או כל ערך שאפשר לקבוע על סמך מאפיינים קיימים.

challenge icon

אתגר

קל

בואו נבנה מחלקת Box שמחשבת את הנפח שלה לפי דרישה! במקום לאחסן את הנפח כשדה, תיצרו מאפיין מחושב שמחשב אותו ממידות התיבה בכל פעם שהוא נדרש.

תארגנו את הקוד שלכם בשני קבצים:

  • Box.lua: הגדירו את מחלקת Box באמצעות תבנית האב־טיפוס המקובלת. כל תיבה שומרת שלוש מידות: width, height, ו-depth. כללו:
    • בנאי :new(width, height, depth) ששומר את שלוש המידות
    • מתודה :getVolume() שמחשבת ומחזירה את הנפח (width × height × depth)
    • מתודה :getSurfaceArea() שמחשבת ומחזירה את שטח הפנים הכולל
  • main.lua: טענו את מודול Box, צרו מופע של תיבה והדגימו כיצד המאפיינים המחושבים משקפים אוטומטית את המידות הנוכחיות.

שטח הפנים של תיבה מחושב כך: 2 × (width×height + height×depth + width×depth)

תקבלו שלוש קלטים שמייצגים את מידות התיבה:

  1. רוחב
  2. גובה
  3. עומק

בקובץ הראשי, צרו תיבה עם המידות הנתונות, ואז הדפיסו שתי שורות:

  1. הנפח באמצעות :getVolume()
  2. שטח הפנים באמצעות :getSurfaceArea()

לדוגמה, אם הקלטים הם 3, 4, ו-5, הפלט צריך להיות:

60
94

היתרון במאפיינים מחושבים הוא שהם תמיד נשארים מדויקים. אם תשנו בהמשך אחת ממידות התיבה, קריאה חוזרת ל-:getVolume() תחזיר אוטומטית את הערך החדש והנכון: אין צורך בעדכונים ידניים!

נסו בעצמכם

-- טען את המודול Box באמצעות require
local Box = require('Box')

-- קרא את הממדים מהקלט
local width = tonumber(io.read())
local height = tonumber(io.read())
local depth = tonumber(io.read())

-- TODO: צור מופע של Box עם הממדים הנתונים

-- TODO: הדפס את הנפח באמצעות :getVolume()

-- TODO: הדפס את שטח הפנים באמצעות :getSurfaceArea()
quiz iconבחנו את עצמכם

השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.

כל השיעורים ביחידה תכנות מונחה עצמים

תרגלו בעצמכם: קומפיילר Lua אונליין