Ключевое слово companion
Ключевое слово companion используется для создания
компаньон объекта внутри класса. Компаньон объект является
объектом, который связан с классом, а не с его экземплярами.
Это позволяет обращаться к свойствам и методам компаньон объекта
напрямую через имя класса, без создания экземпляра класса.
Компаньон объект инициализируется при первом обращении к нему.
Синтаксис
class MyClass {
companion object {
// свойства и методы компаньон объекта
}
}
class MyClass {
companion object Name {
// свойства и методы компаньон объекта с именем
}
}
Пример
Создадим класс с компаньон объектом, содержащим свойство и метод:
class Calculator {
companion object {
val PI = 3.14159
fun add(a: Int, b: Int): Int {
return a + b
}
}
}
Обращение к членам компаньон объекта:
val piValue = Calculator.PI
val sum = Calculator.add(5, 3)
println(piValue)
println(sum)
Результат выполнения кода:
Double 3.14159
Int 8
Пример
Компаньон объект с именем и реализацией интерфейса:
interface Factory {
fun create(): String
}
class Product {
companion object Producer : Factory {
override fun create(): String {
return "Product created"
}
}
}
Использование именованного компаньон объекта:
val product = Product.Producer.create()
println(product)
Результат выполнения кода:
String "Product created"
Пример
Компаньон объект с фабричным методом для создания экземпляров класса:
class User private constructor(val name: String) {
companion object {
fun createUser(name: String): User {
return User(name)
}
}
}
Создание экземпляра через фабричный метод компаньон объекта:
val user = User.createUser("John")
println(user.name)
Результат выполнения кода:
String "John"
Пример
Доступ к приватным членам класса из компаньон объекта:
class Configuration {
private val configData = mutableMapOf<String, Any>()
companion object {
fun createDefault(): Configuration {
val config = Configuration()
config.configData["timeout"] = 30
config.configData["retries"] = 3
return config
}
}
fun getConfig(): Map<String, Any> {
return configData
}
}
Использование фабричного метода:
val config = Configuration.createDefault()
val configData = config.getConfig()
println(configData)
Результат выполнения кода:
Map {timeout=30, retries=3}