Kotlin object, companion object, and delegation

An object declaration creates a singleton: one instance, created on first use, with no need for a static keyword. A companion object holds members that belong to the class itself, such as factory functions. With a private constructor, the only way to build instances is through the factory, which can enforce rules like numbering the instances.

Kotlin
interface Logger {
    fun log(message: String)
}

class ConsoleLogger : Logger {
    override fun log(message: String) = println("LOG: $message")
}

class Service(logger: Logger) : Logger by logger {
    fun run() {
        log("service started")
    }
}

class Counter private constructor(val id: Int) {
    companion object {
        private var next = 1
        fun create(): Counter = Counter(next++)
    }
}

object Config {
    val name = "demo"
    fun describe() = "config $name"
}

fun main() {
    Service(ConsoleLogger()).run()
    println(Counter.create().id)
    println(Counter.create().id)
    println(Config.describe())
}
Read the full lesson