Everything else is just a tool to model your domain in a way that’s easier to read and reason about, and to produce much shorter code. Interfaces define module boundaries and can be mocked to enable simpler testing. Through classes, objects, and data structures, you can model your domain entities. Enums make a list of limited options crystal clear. Extensions allow you to add functionality to existing types, without having access to their original source code, giving advantage of better logic structure. With generics, you can write universal code, promoting reuse. And overloaded operators give that extra edge to common operations that benefit from succinct, crisp syntax.
Enums
Custom types that represent a fixed set of discreet values, a.k.a. enumerations.
Enums
Simple enum:
enum class Direction {
NORTH, SOUTH, WEST, EAST
}
val north = Direction.valueOf("NORTH")
val allDirections = Direction.values()
val alsoAllDirections = Direction.entries
val southInstruction = "Go ${Direction.SOUTH.name}." +
" It has index ${Direction.SOUTH.ordinal} in the enum."
val south = Direction.entries[Direction.SOUTH.ordinal]
An enum class can have properties and methods. Enum values can have parameters, but they cannot be created outside of their enum class. For example, is not possible in the example below.val white = Color(0xFFFFFF)
enum class Color(val rgb: Int) {
RED(0xFF0000),
GREEN(0x00FF00),
BLUE(0x0000FF);
fun poeticName() = when (this) {
RED -> "crimson"
GREEN -> "emerald"
BLUE -> "azure"
}
}
Enums can implement interfaces, but cannot derive from a class. Enum values can customize common members, as well as define new ones, specific to that value.
interface Rateable {
val rating: Double
}
enum class Sentiment(override val rating: Double): Rateable {
HAPPY(1.0),
SAD(-1.0),
NEUTRAL(0.0)
}
enum class Reaction(val emoji: String): Rateable {
LOVE("❤️") {
override val sentiment
get() = Sentiment.HAPPY
override val rating: Double
get() = super.rating * 2
},
LIKE("👍") {
override val sentiment
get() = Sentiment.HAPPY
},
DISLIKE("👎") {
override val sentiment
get() = Sentiment.SAD
},
SURPRISE("😮") {
override val sentiment
get() = Sentiment.NEUTRAL
};
abstract val sentiment: Sentiment
override val rating: Double
get() = sentiment.rating
}