This tutorial is about object declarations (singletons) and object expressions with the help of examples.
Object Declarations
Object declarations defines singletons. Singleton is an object-oriented pattern where a class can have only one instance (object) at a time.
- Kotlin creates singletons with the object keyword.
- The object declaration can have functions, properties, and the init block.
- We can use the init block if some initialisation is required. The init block will be called when your object gets constructed.
- Object declaration’s initialisation is thread-safe and done at first access.
- The constructor method is not allowed in an object.
- To access methods and properties of object, use the object declaration’s name and dot (.) notation.
Example:
//creating object Test object Test { //init block init { println("Singleton class invoked.") } var a: Int = 10 var b: Int = 20 fun add(): Int = a + b } fun main() { //accessing members using object name println("Addition of ${Test.a} and ${Test.b}: ${Test.add()}") }
Output:
Singleton class invoked. Addition of 10 and 20: 30
Objects can also implement interfaces and extend other classes in a similar way like normal classes.
Example:
//object RunnableSingleton implementing interface Runnable
object RunnableSingleton : Runnable {
override fun run() {
println("I'm a runnable singleton")
}
}
Kotlin also allows objects to be declared inside classes. Nested objects cannot access members from the outer class.
//declare an object Singleton inside a class Outer
class Outer {
object Singleton {
}
}
Object Expressions
The object keyword can also be used to create objects of an anonymous class known as anonymous objects.
They are used if you need to create an object of a slight modification of some class or interface without declaring a subclass for it.
Anonymous object implementing an Interface
Let’s create an anonymous object of a Runnable interface:
Example:
Thread(object : Runnable { override fun run() { println("I am anonymous object") } }).run()
If you need a name for your anonymous object, or need it to store for later use, you can initialise a variable with it.
Example:
val runnable = object : Runnable { override fun run() { println("I'm created with anonymous object") } }
Anonymous object implementing a class
Example:
open class Vehicle { fun start() { println("Vehicle is in start mode.") } fun stop() { println("Vehicle is in stop mode.") } open fun park() { println("Vehicle is in park mode.") } } fun main() { val car = object : Vehicle() { override fun park() = println("Car is in park mode.") } car.start() car.stop() car.park() }
Output:
Vehicle is in start mode. Vehicle is in stop mode. Car is in park mode.
Here, anonymous object is stored in variable car which implements Vehicle class with park() method is overridden.