Setters פרטיים
חלק מהיחידה תכנות מונחה עצמים במסלול ה-Kotlin של Coddy. שיעור 9 מתוך 57.
לעיתים קרובות, קוד מחוץ למחלקה צריך לקרוא מאפיין, אך לא לשנות אותו. private set משאיר את ה־getter ציבורי והופך רק את ה־setter לפרטי:
class Counter {
var count = 0
private set
fun increment() {
count++
}
}בתוך main:
val c = Counter()
c.increment()
println(c.count)
// c.count = 99 // שגיאה: פונקציית ההגדרה פרטיתפלט:
1זה מתאים לערכים שיכולים להשתנות רק באמצעות כלל, כמו ניקוד שרק גדל בעקבות הענקת נקודות תקפה:
class Player(val name: String) {
var score = 0
private set
private val _history = mutableListOf<Int>()
val history: List<Int> get() = _history
fun award(points: Int) {
if (points <= 0) return
score += points
_history.add(points)
}
}בתוך main:
val p = Player("Ada")
p.award(10)
p.award(-5)
p.award(3)
println(p.score)
println(p.history)פלט:
13
[10, 3]ה־history שלמעלה מציג תבנית נפוצה: MutableList פרטי בתוך המחלקה, שנחשף כ־List לקריאה בלבד. הקוראים יכולים לקרוא את הפריטים, אך אין להם add או remove שבאמצעותם יוכלו לשנות אותם:
private val _items = mutableListOf<String>()
val items: List<String> get() = _items // תצוגה לקריאה בלבד
// מבחוץ: items.add("x") // שגיאה: ל-List אין addval לעולם אינו משתנה לאחר יצירתו, אפילו לא בתוך המחלקה. var עם private set נשאר ניתן לשינוי רק בתוך המחלקה. בחרו ב־val לערכים קבועים לאורך כל חיי האובייקט:
class Order(val id: Int) { // לעולם אינו משתנה
var status = "new"
private set // משתנה, אבל רק בתוך Order
fun ship() { status = "shipped" }
}אתגר
קלהשלימו את המחלקה Elevator(val topFloor: Int). אפשר לקרוא את floor ואת trips מבחוץ, אך לשנות אותם רק בתוך המחלקה (private set). goTo(target) מעבירה בין קומה 0 ל־topFloor: מעבר תקף לקומה אחרת מעדכן את floor, מוסיף 1 ל־trips ומחזיר true; מעבר לא תקף או מעבר לאותה קומה מחזיר false.
הקוד שסופק קורא את הקומה העליונה ולאחר מכן את קומות היעד. הוא מדפיס floor 3 לאחר מעבר או stay 3 כאשר המעבר נדחה, ולבסוף trips: יחד עם המספר.
הקוד שלכם צריך להיכתב בקובץ Elevator.kt. הקובץ Main.kt מכיל את קוד הקלט/פלט שסופק ואי אפשר לערוך אותו.
נסו בעצמכם
fun main() {
// קוד הקלט/פלט שסופק: יש להשאיר אותו כפי שהוא
val input = generateSequence(::readLine).toList()
val lift = Elevator(input[0].toInt())
for (line in input.drop(1)) {
val moved = lift.goTo(line.toInt())
println("${if (moved) "floor" else "stay"} ${lift.floor}")
}
println("trips: ${lift.trips}")
}
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה תכנות מונחה עצמים
1מחלקות ואובייקטים
עבודה עם קבציםהגדרת מחלקותבנאים ראשייםבלוקי init ואימות נתוניםבנאים משנייםסיכום – כרטיס ספרייהתרגלו בעצמכם: Kotlin אונליין