Accessors מותאמים אישית
חלק מהיחידה תכנות מונחה עצמים במסלול ה-Kotlin של Coddy. שיעור 7 מתוך 57.
לכל מאפיין ב-Kotlin יש getter, ולכל var יש גם setter. כברירת מחדל, הם קוראים ערך שמור וכותבים אליו. גטר מותאם אישית מחשב את הערך בכל קריאה במקום זאת:
class Rectangle(var width: Int, var height: Int) {
val area: Int
get() = width * height
}בתוך main:
val r = Rectangle(3, 4)
println(r.area)
r.width = 10
println(r.area)פלט:
12
40מגדיר מותאם אישית מריץ קוד בכל פעם שמשייכים ערך למאפיין. בתוכו, value הוא הערך שהוקצה, ו-field הוא הערך המאוחסן מאחורי המאפיין, שדה הגיבוי:
class Thermostat {
var target = 20
set(value) {
field = value.coerceIn(10, 30)
}
}בתוך main:
val t = Thermostat()
t.target = 42
println(t.target)
t.target = 18
println(t.target)פלט:
30
18בתוך אקססור, השתמשו ב־field, ולא בשם המאפיין: כתיבה של target = value בתוך ה־setter של target תפעיל שוב את ה־setter, לנצח:
var target = 20
set(value) {
// target = value // קורא שוב ל-setter הזה: רקורסיה אינסופית
field = value // מאחסן את הערך
}גם setter הוא המקום להגיב לשינויים, למשל לספור אותם או לתעד אותם:
class Player(name: String) {
var changes = 0
private set
var name = name
set(value) {
field = value.trim()
changes++
}
}בתוך main:
val p = Player("ada")
p.name = " Ada "
p.name = "Ada L."
println("${p.name} after ${p.changes} changes")פלט:
Ada L. after 2 changesאתגר
קלהשלם את המחלקה Circle(radius: Double). radius הוא var שה־setter שלו שומר ערכים שליליים כ־0. הוסף את המאפיינים לקריאה בלבד diameter ו־area (π r² באמצעות Math.PI) עם getters מותאמים אישית, ואת label, שמחזיר r=2.0 d=4.0 a=12.57 כשהשטח מעוגל לשתי ספרות אחרי הנקודה ("%.2f".format(area)).
הקוד שסופק קורא רדיוס אחד בכל שורה, מדפיס label, ואז מכפיל פי שניים את הרדיוס של המעגל האחרון ומדפיס שוב label, ולכן הערכים חייבים להתעדכן בהתאם לרדיוס.
הקוד שלך צריך להופיע ב־Circle.kt. Main.kt מכיל את קוד הקלט/פלט שסופק ואי אפשר לערוך אותו.
נסו בעצמכם
fun main() {
// קוד הקלט/פלט שסופק: יש להשאיר אותו כפי שהוא
val input = generateSequence(::readLine).toList()
var last = Circle(0.0)
for (line in input) {
last = Circle(line.toDouble())
println(last.label)
}
last.radius *= 2
println(last.label)
}
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה תכנות מונחה עצמים
1מחלקות ואובייקטים
עבודה עם קבציםהגדרת מחלקותבנאים ראשייםבלוקי init ואימות נתוניםבנאים משנייםסיכום – כרטיס ספרייהתרגלו בעצמכם: Kotlin אונליין