Menu
Coddy logo textTech

העמקה ב-getters וב-setters

חלק מהיחידה תכנות מונחה עצמים במסלול ה-Dart של Coddy. שיעור 33 מתוך 110.

גטרים וסטרים הופכים לכלים רבי־עוצמה לאנקפסולציה כאשר משלבים אותם עם שדות פרטיים. הם מאפשרים לחשוף ממשק ציבורי נקי תוך שמירה על שליטה מלאה באופן הגישה לנתונים ושינוי שלהם.

תבנית נפוצה היא צימוד של שדה פרטי עם getter ציבורי ו־setter הכולל אימות:

class Temperature {
  double _celsius = 0;
  
  double get celsius => _celsius;
  
  set celsius(double value) {
    if (value < -273.15) {
      _celsius = -273.15;  // המינימום הוא האפס המוחלט
    } else {
      _celsius = value;
    }
  }
}

מתודות הגדרה יכולות לאכוף כללים עסקיים ולהבטיח שהאובייקט שלך לעולם לא יגיע למצב לא תקין.

אפשר גם ליצור גטרים מחושבים שמפיקים ערכים מנתונים פרטיים:

class Rectangle {
  double _width;
  double _height;
  
  Rectangle(this._width, this._height);
  
  double get area => _width * _height;      // מחושב
  double get perimeter => 2 * (_width + _height);
  
  double get width => _width;
  set width(double value) {
    if (value > 0) _width = value;
  }
}

לפעמים רוצים גישה לקריאה בלבד. פשוט מספקים getter בלי setter:

class Order {
  final DateTime _createdAt = DateTime.now();
  
  DateTime get createdAt => _createdAt;  // לקריאה בלבד
}

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

challenge icon

אתגר

קל

בואו נבנה מערכת לניהול מלאי מוצרים שמדגימה את העוצמה של getters ו-setters בשליטה בגישה לנתונים. תיצרו מחלקה שמגינה על הנתונים הפנימיים שלה, ובמקביל מספקת מאפיינים מחושבים ואימות.

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

  • product.dart: הגדירו מחלקת Product שמנהלת מלאי באמצעות כימוס מתאים. למוצר שלכם צריכים להיות:
    • String name ציבורי
    • double _price פרטי
    • int _quantity פרטי
    • בנאי שמקבל את שלושת הערכים
    • getter בשם price שמחזיר את המחיר הפרטי
    • setter בשם price שמקבל רק ערכים הגדולים מ-0 (התעלמו מערכים לא תקינים)
    • getter בשם quantity שמחזיר את הכמות הפרטית
    • setter בשם quantity שמקבל רק ערכים של 0 ומעלה (התעלמו מערכים שליליים)
    • getter מחושב בשם totalValue שמחזיר את _price * _quantity
    • getter מחושב בשם isInStock שמחזיר true אם הכמות גדולה מ-0
    • getter לקריאה בלבד בשם sku שיוצר SKU פשוט על ידי החזרת 3 התווים הראשונים של השם באותיות גדולות, ולאחריהם הכמות (לדוגמה, LAP25 עבור "Laptop" עם כמות 25)
    • מתודה displayProduct() שמציגה את פרטי המוצר
  • main.dart: ייבאו את מחלקת המוצר שלכם והדגימו כיצד getters ו-setters שולטים בגישה:
    • צרו מוצר בשם 'Laptop' עם מחיר 999.99 וכמות 25
    • קראו ל-displayProduct()
    • הדפיסו In stock: [isInStock]
    • הדפיסו SKU: [sku]
    • נסו להגדיר את המחיר ל--50.0 (יש להתעלם מהערך)
    • הגדירו את המחיר ל-899.99 (שינוי תקין)
    • נסו להגדיר את הכמות ל--10 (יש להתעלם מהערך)
    • הגדירו את הכמות ל-0 (שינוי תקין)
    • קראו ל-displayProduct()
    • הדפיסו In stock: [isInStock]
    • הדפיסו SKU: [sku]

המתודה displayProduct() צריכה להדפיס בפורמט הזה:

--- Product Info ---
Name: [name]
Price: $[price]
Quantity: [quantity]
Total Value: $[totalValue]

פלט צפוי:

--- Product Info ---
Name: Laptop
Price: $999.99
Quantity: 25
Total Value: $24999.75
In stock: true
SKU: LAP25
--- Product Info ---
Name: Laptop
Price: $899.99
Quantity: 0
Total Value: $0.0
In stock: false
SKU: LAP0

נסו בעצמכם

import 'product.dart';

void main() {
  // TODO: צרו מוצר בשם 'Laptop' שמחירו 999.99 והכמות שלו היא 25

  // TODO: קראו ל־displayProduct()

  // TODO: הדפיסו "In stock: [isInStock]"

  // TODO: הדפיסו "SKU: [sku]"

  // TODO: נסו להגדיר את המחיר ל־-50.0 (יש להתעלם מהשינוי)

  // TODO: הגדירו את המחיר ל־899.99 (שינוי תקין)

  // TODO: נסו להגדיר את הכמות ל־-10 (יש להתעלם מהשינוי)

  // TODO: הגדירו את הכמות ל־0 (שינוי תקין)

  // TODO: קראו ל־displayProduct()

  // TODO: הדפיסו "In stock: [isInStock]"

  // TODO: הדפיסו "SKU: [sku]"
}
quiz iconבחנו את עצמכם

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

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

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