Classes, Data Classes, and Objects
Classes with a primary constructor
class Student(val name: String, var xp: Int = 0) {
fun gainXp(amount: Int) {
xp += amount
}
}
val ada = Student("Ada")
ada.gainXp(50)
println(ada.xp) // 50
Declaring val name: String directly inside the class header does three things at once: declares a constructor parameter, creates a property, and generates its getter (and a setter too, for var properties), all without writing a single line of boilerplate. Compare that to Java's Methods and Classes lesson, where the constructor, field, and getter each had to be written out by hand.
Data classes
When a class exists mainly to hold data, data class generates equals(), hashCode(), toString(), and a handy copy() for you:
data class Point(val x: Int, val y: Int)
val p1 = Point(1, 2)
val p2 = Point(1, 2)
println(p1 == p2) // true, structural equality, not reference equality
println(p1) // Point(x=1, y=2)
val p3 = p1.copy(y = 5) // Point(x=1, y=5), everything else copied as-is
p1 == p2 is true even though they're two separate objects, because data class compares by value, not by memory reference, exactly what you want for simple data-holding types.
object and companion object
object declares a class with exactly one instance, a singleton, created lazily the first time it's used:
object Config {
val maxRetries = 3
}
println(Config.maxRetries)
A companion object attaches shared, class-level members to a regular class, similar to static in Java:
class User(val id: Int) {
companion object {
fun createGuest() = User(0)
}
}
val guest = User.createGuest()