Menu
Coddy logo textTech

מתודות ברירת מחדל

חלק מהיחידה תכנות מונחה עצמים במסלול ה-Kotlin של Coddy. שיעור 23 מתוך 57.

למתודה בממשק יכול להיות גוף. מימוש ברירת המחדל הזה משמש כל מחלקה שאינה מבצעת לו דריסה:

interface Greeter {
    val name: String
    fun greet() = "Hello, I am $name"
}
class Robot(override val name: String) : Greeter
class Pirate(override val name: String) : Greeter {
    override fun greet() = "Ahoy! $name here"
}

בתוך main:

println(Robot("R2").greet())
println(Pirate("Anne").greet())

פלט:

Hello, I am R2
Ahoy! Anne here

מתודות ברירת מחדל נכתבות במונחים של שאר החברים בממשק. מחלקה מספקת את החברים המעטים ששונים ומקבלת את השאר:

interface Priced {
    val cents: Int
    fun formatted() = "$%d.%02d".format(cents / 100, cents % 100)
    fun isAffordable(budget: Int) = cents <= budget
}
class Coffee : Priced {
    override val cents = 450
}

בתוך main:

val c = Coffee()
println(c.formatted())
println(c.isAffordable(400))

פלט:

$4.50
false

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

interface Box {
    val width: Int
    val height: Int
    val area: Int
        get() = width * height
    // val count = 0      // שגיאה: אתחול מאפיינים אינו מותר בממשקים
}
class Tile(override val width: Int, override val height: Int) : Box

בתוך main:

println(Tile(3, 4).area)

פלט:

12

מימוש חלופי עדיין יכול להשתמש במימוש ברירת המחדל. בתוך המחלקה, super.method() קוראת לגרסה של הממשק:

interface Priced {
    val cents: Int
    fun formatted() = "$%d.%02d".format(cents / 100, cents % 100)
}
class Coffee : Priced {
    override val cents = 450
    override fun formatted() = "coffee " + super.formatted()
}

בתוך main:

println(Coffee().formatted())

פלט:

coffee $4.50
challenge icon

אתגר

קל

לממשק Priced יש price (בסנטים). הוסיפו לו מימוש ברירת מחדל של formatted() שמחזיר $4.50, ומימוש ברירת מחדל של isAffordable(budget) שמחזיר האם המחיר אינו עולה על התקציב. העלות של Coffee היא 450, והוא מחליף את formatted() ב-coffee $4.50, תוך שימוש חוזר במימוש ברירת המחדל באמצעות super. Sandwich(price) משתמש בשני מימושי ברירת המחדל.

הקוד שסופק קורא תקציב בסנטים ולאחר מכן שורות coffee או sandwich,650. הוא מדפיס את formatted() ואת yes או no עבור כל פריט.

הקוד שלך ייכתב בקבצים Priced.kt, Coffee.kt ו-Sandwich.kt. הקובץ Main.kt מכיל את קוד הקלט/פלט שסופק, ואי אפשר לערוך אותו.

נסו בעצמכם

fun main() {
    // קוד קלט/פלט שסופק: יש להשאיר אותו כפי שהוא
    val input = generateSequence(::readLine).toList()
    val budget = input[0].toInt()
    for (line in input.drop(1)) {
        val p = line.split(",")
        val item: Priced = if (p[0] == "coffee") Coffee() else Sandwich(p[1].toInt())
        println("${item.formatted()} ${if (item.isAffordable(budget)) "yes" else "no"}")
    }
}
quiz iconבחנו את עצמכם

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

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

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