Spec-Zone.ru › Kotlin 2

Объекты

В этой главе вы углубите свои знания о классах, изучив объявления объектов. Эти знания помогут вам эффективно управлять поведением в проектах.

Объявления объектов

В Kotlin можно использовать объявления объектов, чтобы объявить класс с единственным экземпляром. В некотором смысле вы объявляете класс и создаёте единственный экземпляр одновременно. Объявления объектов полезны, когда вы хотите создать класс, который будет единой точкой обращения для программы, или координировать поведение в системе.

Класс, у которого есть только один легко доступный экземпляр, называется синглтоном.

Объекты в Kotlin создаются лениво, то есть только при обращении к ним. Kotlin также гарантирует потокобезопасное создание всех объектов, поэтому вам не нужно проверять это вручную.

Чтобы создать объявление объекта, используйте ключевое слово object:

object DoAuth {}

После имени object добавьте любые свойства или функции-члены в тело объекта, ограниченное фигурными скобками {}.

У объектов не может быть конструкторов, поэтому у них нет заголовков, как у классов.

Например, допустим, вы хотите создать объект с именем DoAuth, отвечающий за аутентификацию:

object DoAuth {
    fun takeParams(username: String, password: String) {
        println("input Auth parameters = $username:$password")
    }
}

fun main(){
    // The object is created when the takeParams() function is called
    DoAuth.takeParams("coding_ninja", "N1njaC0ding!")
    // input Auth parameters = coding_ninja:N1njaC0ding!
}

У объекта есть функция-член с именем takeParams, которая принимает переменные username и password в качестве параметров и выводит строку в консоль. Объект DoAuth создаётся только при первом вызове функции.

Объекты могут наследоваться от классов и интерфейсов. Например:

interface Auth {
    fun takeParams(username: String, password: String)
}

object DoAuth : Auth {
    override fun takeParams(username: String, password: String) {
        println("input Auth parameters = $username:$password")
    }
}

Объекты данных

Чтобы упростить вывод содержимого объявления объекта, в Kotlin есть объекты данных. Как и классы данных, о которых вы узнали в вводном курсе, объекты данных автоматически получают дополнительные функции-члены: toString() и equals().

В отличие от классов данных, объекты данных не получают автоматически функцию-член copy(), поскольку у них есть только один экземпляр, который нельзя скопировать.

Чтобы создать объект данных, используйте тот же синтаксис, что и для объявления объекта, добавив перед ним ключевое слово data:

data object AppConfig {}

Например:

data object AppConfig {
    var appName: String = "My Application"
    var version: String = "1.0.0"
}

fun main() {
    println(AppConfig)
    // AppConfig
    
    println(AppConfig.appName)
    // My Application
}

Дополнительную информацию об объектах данных см. в разделе Объекты данных.

Объекты-компаньоны

В Kotlin у класса может быть объект — объект-компаньон. У класса может быть только один объект-компаньон. Объект-компаньон создаётся только при первом обращении к его классу.

Все свойства и функции, объявленные внутри объекта-компаньона, доступны всем экземплярам класса.

Чтобы создать объект-компаньон внутри класса, используйте тот же синтаксис, что и для объявления объекта, добавив перед ним ключевое слово companion:

companion object Bonger {}

Объект-компаньон может быть без имени. Если вы не зададите имя, по умолчанию будет использовано Companion.

Чтобы обратиться к свойствам или функциям объекта-компаньона, укажите имя класса. Например:

class BigBen {
    companion object Bonger {
        fun getBongs(nTimes: Int) {
            repeat(nTimes) { print("BONG ") }
            }
        }
    }

fun main() {
    // Companion object is created when the class is referenced for the
    // first time.
    BigBen.getBongs(12)
    // BONG BONG BONG BONG BONG BONG BONG BONG BONG BONG BONG BONG 
}

В этом примере создаётся класс с именем BigBen, содержащий объект-компаньон с именем Bonger. В объекте-компаньоне есть функция-член с именем getBongs(), которая принимает целое число и выводит "BONG" в консоль столько раз, сколько указано в этом числе.

В функции main() функция getBongs() вызывается с помощью имени класса. В этот момент создаётся объект-компаньон. Функция getBongs() вызывается с параметром 12.

Дополнительную информацию см. в разделе Объекты-компаньоны.

Практика

Упражнение 1

Вы управляете кофейней и используете систему для отслеживания заказов клиентов. Рассмотрите приведённый ниже код и дополните объявление второго объекта данных, чтобы следующий код в функции main() выполнялся успешно:

interface Order {
    val orderId: String
    val customerName: String
    val orderTotal: Double
}

data object OrderOne: Order {
    override val orderId = "001"
    override val customerName = "Alice"
    override val orderTotal = 15.50
}

data object // Write your code here

fun main() {
    // Print the name of each data object
    println("Order name: $OrderOne")
    // Order name: OrderOne
    println("Order name: $OrderTwo")
    // Order name: OrderTwo

    // Check if the orders are identical
    println("Are the two orders identical? ${OrderOne == OrderTwo}")
    // Are the two orders identical? false

    if (OrderOne == OrderTwo) {
        println("The orders are identical.")
    } else {
        println("The orders are unique.")
        // The orders are unique.
    }

    println("Do the orders have the same customer name? ${OrderOne.customerName == OrderTwo.customerName}")
    // Do the orders have the same customer name? false
}
interface Order { val orderId: String val customerName: String val orderTotal: Double } data object OrderOne: Order { override val orderId = "001" override val customerName = "Alice" override val orderTotal = 15.50 } data object OrderTwo: Order { override val orderId = "002" override val customerName = "Bob" override val orderTotal = 12.75 } fun main() { // Print the name of each data object println("Order name: $OrderOne") // Order name: OrderOne println("Order name: $OrderTwo") // Order name: OrderTwo // Check if the orders are identical println("Are the two orders identical? ${OrderOne == OrderTwo}") // Are the two orders identical? false if (OrderOne == OrderTwo) { println("The orders are identical.") } else { println("The orders are unique.") // The orders are unique. } println("Do the orders have the same customer name? ${OrderOne.customerName == OrderTwo.customerName}") // Do the orders have the same customer name? false }

Упражнение 2

Создайте объявление объекта, наследующего интерфейс Vehicle, чтобы создать уникальный тип транспортного средства: FlyingSkateboard. Реализуйте свойство name и функцию move() в объекте, чтобы следующий код в функции main() выполнялся успешно:

interface Vehicle {
    val name: String
    fun move(): String
}

object // Write your code here

fun main() {
    println("${FlyingSkateboard.name}: ${FlyingSkateboard.move()}")
    // Flying Skateboard: Glides through the air with a hover engine
    println("${FlyingSkateboard.name}: ${FlyingSkateboard.fly()}")
    // Flying Skateboard: Woooooooo
}
interface Vehicle { val name: String fun move(): String } object FlyingSkateboard : Vehicle { override val name = "Flying Skateboard" override fun move() = "Glides through the air with a hover engine" fun fly(): String = "Woooooooo" } fun main() { println("${FlyingSkateboard.name}: ${FlyingSkateboard.move()}") // Flying Skateboard: Glides through the air with a hover engine println("${FlyingSkateboard.name}: ${FlyingSkateboard.fly()}") // Flying Skateboard: Woooooooo }

Упражнение 3

Вы создаёте модуль регистрации пользователей для приложения. Вы хотите связать проверку адреса электронной почты с классом User, но не хотите создавать ненужный экземпляр User, если адрес электронной почты недействителен.

Для этого упражнения считайте адрес электронной почты действительным, если он содержит и @, и .. Дополните класс данных так, чтобы следующий код в функции main() выполнялся успешно:

Подсказка

Добавьте функцию проверки адреса электронной почты в объект-компаньон класса `User`, чтобы вызывать эту функцию непосредственно у `User`.

data class User(val name: String, val email: String) {
    // Write your code here
}

fun main() {
    val candidates = listOf(
        Pair("Alice", "alice@example.com"),
        Pair("Bob", "bob2example-com")
    )

    for ((name, email) in candidates) {
        if (User.isValidEmail(email)) {
            val user = User(name, email)
            println("Registered: ${user.name}, ${user.email}")
            // Registered: Alice, alice@example.com
        } else {
            println("Error: '${email}' is not valid. The email should contain '@' and '.'")
            // Error: 'bob2example-com' is not valid. The email should contain '@' and '.'
        }
    }
}
data class User(val name: String, val email: String) { companion object { fun isValidEmail(email: String): Boolean = email.contains('@') && email.contains('.') } } fun main() { val candidates = listOf( Pair("Alice", "alice@example.com"), Pair("Bob", "bob2example-com") ) for ((name, email) in candidates) { if (User.isValidEmail(email)) { val user = User(name, email) println("Registered: ${user.name}, ${user.email}") // Registered: Alice, alice@example.com } else { println("Error: '${email}' is not valid. The email should contain '@' and '.'") // Error: 'bob2example-com' is not valid. The email should contain '@' and '.' } } }

В качестве дополнительного задания попробуйте использовать функции объектов-компаньонов как фабричные методы для создания экземпляров класса. Пример и дополнительную информацию об этом шаблоне см. в разделе Объекты-компаньоны.

  • Предыдущий шаг

  • Следующий шаг

1 сентября 2026 г.
Классы и интерфейсыОткрытые и специальные классы

© 2010–2026 JetBrains s.r.o. and Kotlin Programming Language contributors
Licensed under the Apache License, Version 2.0.
https://kotlinlang.org/docs/kotlin-tour-intermediate-objects.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API