English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
In this article, you will learn about object declarations (singletons) and object expressions with the help of examples.
A singleton is an object-oriented pattern where a class can have only one instance (object).
For example, if you are developing an application with an SQL database backend, you want to create a connection pool to access the database and reuse the same connection for all clients. For this purpose, you can create a connection through a singleton class so that each client gets the same connection.
Kotlin provides a simple way to create singletons using the object declaration feature. For this, use the object keyword.
object SingletonExample { ... .. ... //Class body ... .. ... }
The above code combines a class declaration with the declaration of a single instance of the class SingletonExample
Object declarations can include properties, methods, etc., but they do not allow a constructor (which is reasonable).
Similar to objects of ordinary classes, you can use the . symbol to call methods and access properties.
object Test { private var a: Int = 0 var b: Int = 1 fun makeMe12(): Int { a = 12 return a } } fun main(args: Array<String>) { val result: Int result = Test.makeMe12() println("b = ${Test.b}") println("result = $result") }
The output when running the program is:
b = 1 result = 12
Object declarations can inherit from classes and interfaces like ordinary classes.
Object declarations can sometimes be very useful. However, they are not ideal in large software systems with many interactions with other parts of the system.
The object keyword can also be used to create objects of anonymous classes, known as anonymous objects. If it is necessary to create an object that slightly modifies a class or interface without declaring a subclass, they can be used. For example,
window.addMouseListener(object : MouseAdapter() { override fun mouseClicked(e: MouseEvent) { // ... } override fun mouseEntered(e: MouseEvent) { // ... } }
Here, an anonymous object that extends the MouseAdapter class is declared. The program overrides two MouseAdapter methods: mouseClicked() and mouseEntered().
If necessary, a name can be assigned to an anonymous object and stored in a variable. For example:
val obj = object : MouseAdapter() { override fun mouseClicked(e: MouseEvent) { // ... } override fun mouseEntered(e: MouseEvent) { // ... } }
open class Person() { fun eat() = println("Eat food.") fun talk() = println("Talk with people.") open fun pray() = println("Pray to God.")}} } fun main(args: Array<String>) { val atheist = object : Person() { override fun pray() = println("I don't pray. I am an atheist.") } atheist.eat() atheist.talk() atheist.pray() }
The output when running the program is:
Eat something. Talk to people. I don't pray. I am an atheist.
Here, the anonymous object is stored in the variable atheist, which implements the Person class, and the pray() method is overridden.
If the class implements a constructor that declares an anonymous object, then appropriate constructor parameters must be passed. For example,
open class Person(name: String, age: Int) { init { println("name: $name, age: $age") } fun eat() = println("Eat food.") fun talk() = println("Talk with people.") open fun pray() = println("Pray to God.")}} } fun main(args: Array<String>) { val atheist = object : Person("Jack", 29) { override fun pray() = println("I don't pray. I am an atheist.") } atheist.eat() atheist.talk() atheist.pray() }
The output when running the program is:
name: Jack, age: 29 Eat something. Talk to people. I don't pray. I am an atheist.