Menu
Coddy logo textTech

מחלקות Enum

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

מחלקת enum class מכריזה על טיפוס עם קבוצה קבועה של ערכים, הקבועים שלו. כל קבוע הוא אובייקט של ה-enum עם name ו-ordinal, המיקום שלו שמתחיל ב-0. entries מציג אותם לפי הסדר:

enum class Direction { NORTH, EAST, SOUTH, WEST }

בתוך main:

val d = Direction.EAST
println(d)
println(d.ordinal)
println(Direction.entries)

פלט:

EAST
1
[NORTH, EAST, SOUTH, WEST]

לקבועי enum יכולים להיות מאפיינים, שמועברים לבנאי של enum, ו-enum יכול להגדיר מתודות. נקודה־פסיק מסיימת את רשימת הקבועים לפני האיברים:

enum class Coin(val cents: Int) {
    PENNY(1), NICKEL(5), DIME(10), QUARTER(25);

    fun label() = "${name.lowercase()} ($cents c)"
}

בתוך main:

println(Coin.DIME.label())
println(Coin.entries.sumOf { it.cents })

פלט:

dime (10 c)
41

ביטוי when על enum שמציין כל קבוע אינו זקוק ל־else, והמהדר מדווח על קבוע שחסר. valueOf("SOUTH") מוצא קבוע לפי שמו המדויק וזורק חריגה אם הוא לא מוכר, לכן בדרך כלל מתאימים קלט באמצעות entries.find:

enum class Direction { NORTH, EAST, SOUTH, WEST }

fun turnRight(d: Direction) = when (d) {
    Direction.NORTH -> Direction.EAST
    Direction.EAST -> Direction.SOUTH
    Direction.SOUTH -> Direction.WEST
    Direction.WEST -> Direction.NORTH
}

fun parse(text: String) = Direction.entries.find { it.name == text.uppercase() }

בתוך main:

println(turnRight(Direction.valueOf("SOUTH")))
println(parse("north"))
println(parse("up"))

פלט:

WEST
NORTH
null

לקבוע יכול להיות גוף משלה ולדרוס בו מתודה. הכרזה על המתודה abstract בתוך ה-enum מאלצת כל קבוע לממש אותה:

enum class Op(val symbol: String) {
    PLUS("+") {
        override fun apply(a: Int, b: Int) = a + b
    },
    TIMES("*") {
        override fun apply(a: Int, b: Int) = a * b
    };

    abstract fun apply(a: Int, b: Int): Int
}

בתוך main:

for (op in Op.entries) println("6 ${op.symbol} 3 = ${op.apply(6, 3)}")

פלט:

6 + 3 = 9
6 * 3 = 18
challenge icon

אתגר

קל

השלימו את ה-enum Size עם הקבועים SMALL (250 ml, מחיר 300), MEDIUM (350 ml, 380) ו-LARGE (500 ml, 450), כשהמחירים נקובים בסנטים. label() מחזירה medium (350 ml): 3.80, ו-upsize() מחזירה את הגודל הבא אחריו, או את אותו הגודל עבור LARGE. הפונקציה parse(text) של ה-companion מוצאת גודל לפי שמו, ללא תלות באותיות גדולות או קטנות, או לפי האות הראשונה שלו (s, M), ומחזירה null אחרת.

הקוד שסופק קורא הזמנות כגון medium, L או up small (המשקה שהוגדל) ומדפיס כל תווית או unknown size x, ולבסוף total: 11.10.

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

נסו בעצמכם

fun main() {
    // קוד הקלט/פלט שסופק: יש להשאיר אותו כפי שהוא
    val input = generateSequence(::readLine).toList()
    var total = 0
    for (line in input) {
        val upsize = line.startsWith("up ")
        val size = Size.parse(line.removePrefix("up "))
        if (size == null) {
            println("unknown size $line")
            continue
        }
        val chosen = if (upsize) size.upsize() else size
        println(chosen.label())
        total += chosen.price
    }
    println("total: %d.%02d".format(total / 100, total % 100))
}
quiz iconבחנו את עצמכם

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

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

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