Бесплатный вебинар
«как найти любимую работу»
Подарки на 150 000 ₽ за участие
Живой эфир
Записи не будет!
00:00:00:00
дн.ч.мин.сек.

Создание анонимного класса от абстрактного в Kotlin

Быстрый ответ

Для инициализации экземпляра абстрактного класса в Kotlin используется объектное выражение:

kotlin
Скопировать код
abstract class AbstractFoo {
    abstract fun bar()
}

val myObject = object : AbstractFoo() {
    override fun bar() {
        println("Действие дня: Bar!")
    }
}

В приведенном примере мы переопределяем абстрактный метод, оформляя его реализацию с помощью фигурных скобок, так создается анонимный класс.

Кинга Идем в IT: пошаговый план для смены профессии

Разбор объектных выражений

В каких случаях стоит использовать объектное выражение

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

Подробнее об этом расскажет наш спикер на видео
skypro youtube speaker

Отличие Kotlin от Java

В Java для управления событиями в пользовательском интерфейсе часто используют анонимные классы. В Kotlin вместо этого используется слово object, что делает код более лаконичным:

Java
Скопировать код
// Подход Java
Window.addMouseListener(new MouseAdapter() {
    public void mouseClicked(MouseEvent e) {
        System.out.println("Я Java, и меня кликнули.");
    }
});
kotlin
Скопировать код
// Подход Kotlin
window.addMouseListener(object : MouseAdapter() {
    override fun mouseClicked(e: MouseEvent) {
        println("Я Kotlin. Классный клик!")
    }
})

Kotlin отсекает излишние детали, упрощая чтение кода.

Преобразование SAM (Single Abstract Method)

Для функциональных интерфейсов с единственным методом Kotlin предлагает возможность SAM-преобразования:

kotlin
Скопировать код
// Без SAM-преобразования
val runnable = object : Runnable {
    override fun run() {
        println("Бегите, как будто за финишной чертой вас ждёт приз!")
    }
}

// С SAM-преобразованием
val runnable = Runnable { println("Я бегу легко и непринуждённо, благодаря SAM!") }

Однако стоит отметить, что SAM-преобразование доступно только для интерфейсов Java, а не для тех, что определены в Kotlin.

Продвинутые сценарии

Реализация нескольких интерфейсов

В Kotlin вы можете реализовать несколько интерфейсов одновременно при помощи одного анонимного класса:

kotlin
Скопировать код
interface A {
    fun doSomethingA()
}

interface B {
    fun doSomethingB()
}

val myObject = object : A, B {
    override fun doSomethingA() {
        println("Я занимаюсь делом A!")
    }

    override fun doSomethingB() {
        println("И занимаюсь делом B тоже!")
    }
}

Наследование и интерфейсы вместе

В Kotlin один анонимный класс может расширить существующий класс и реализовать интерфейс:

kotlin
Скопировать код
open class C {
    open fun foo() {}
}

interface D {
    fun bar()
}

val myObject = object : C(), D {
    override fun foo() {
        println("Переопределяю foo из C. Не волнуйтесь, всё будет рифмоваться с moo.")
    }

    override fun bar() {
        println("И реализую bar из D. И это не шутка.")
    }
}

Переопределение свойств

В анонимных классах Kotlin также разрешается переопределение свойств, что позволяет индивидуализировать экземпляр:

kotlin
Скопировать код
abstract class Vehicle {
    abstract val numberOfWheels: Int
    abstract fun ride()
}

val bike = object : Vehicle() {
    override val numberOfWheels = 2
    override fun ride() {
        println("Еду на $numberOfWheels колёсах, но это не велосипед!")
    }
}

Визуализация

Создание анонимного класса на основе абстрактного класса в Kotlin можно сравнить с подготовкой импровизированного представления:

kotlin
Скопировать код
// Ваш абстрактный шаблон класса:
abstract class AbstractActor {
    abstract fun perform()
}

// Ваш уникальный сценарий:
val actor = object : AbstractActor() {
    override fun perform() {
        // Проявите свой талант!
    }
}

AbstractActor — это ваша творческая площадка. С помощью perform вы становитесь звездой своего уникального шоу.

Будьте внимательны!

SAM-преобразование и интерфейсы Kotlin

Распространенная ошибка — это применение SAM-преобразования к интерфейсам Kotlin. Это невозможно без использования функциональных типов или inline-классов.

Inline-функции и объектные выражения

В inline-функциях нельзя использовать объектные выражения, если они не реализуют fun-интерфейс:

kotlin
Скопировать код
inline fun inlineFoo(crossinline action: () -> Unit) {
    val myObject = object : Runnable {
        override fun run() = action()
    }
    // Недопустимо: литеральные выражения объектов запрещены в inline-функциях 
}

Лямбды могут служить альтернативой для обхода этого ограничения.

Инициализация свойств в объектных выражениях

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

kotlin
Скопировать код
abstract class SomeAbstractClass {
    abstract val someProperty: String
}

val myObject = object : SomeAbstractClass() {
    override val someProperty = computeExpensiveValue()
    // Внимание: инициализация происходит при создании экземпляра
}

Полезные материалы

  1. Официальная документация Kotlin – подробное описание использования объектных выражений и анонимных классов.
  2. Статья на Medium – содержит ценные советы по переводу кода из Java в Kotlin.
  3. Kotlin Playground – обучение Kotlin на практических примерах.
  4. Baeldung – вводное руководство по анонимным внутренним классам в Kotlin.
  5. Руководство для разработчиков Android – полный материал о Kotlin в контексте Android.
  6. Kodeco – для тех, кто стремится углубить свои знания Kotlin.
Проверь как ты усвоил материалы статьи
Пройди тест и узнай насколько ты лучше других читателей
Как в Kotlin создается анонимный класс от абстрактного класса?
1 / 5