Kotlin Academy · Урок

Свойства-расширения и вычисляемые расширения

Добавляйте вычисляемые свойства к существующим классам без создания подклассов.

Урок 2 из 413 шагов

«Свойства-расширения и вычисляемые расширения» — бесплатный урок Kotlin Academy на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Kotlin Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Kotlin Academy содержит 4 уроков всего.

Свойства-расширения

Свойства-расширения добавляют вычисляемые свойства к существующим типам без создания подклассов. У них нет резервного поля.

Свойство-расширение только для чтения

Определите геттер, чтобы создать вычисляемое свойство-расширение.
val String.wordCount: Int
    get() = trim().split(Regex("\\s+")).size
println("hello world kotlin".wordCount)  // 3

Изменяемое свойство-расширение

Определите и геттер, и сеттер для свойства-расширения, доступного для чтения и записи.
var MutableList<Int>.first: Int
    get() = this[0]
    set(value) { this[0] = value }
val list = mutableListOf(1, 2, 3)
list.first = 10
println(list)  // [10, 2, 3]

Нет резервного поля

У свойств-расширений не может быть резервных полей. Они всегда вычисляются на основе существующего состояния.
// ERROR: extension property cannot have backing field
// var String.cache: String = ""  // NOT allowed!

// OK: computed only:
val String.isPalindrome: Boolean
    get() = this == this.reversed()

Свойства-расширения для коллекций

Добавляйте удобные свойства к типам коллекций.
val <T> List<T>.secondOrNull: T?
    get() = if (size >= 2) this[1] else null
val <T> List<T>.isNotNullOrEmpty: Boolean
    get() = isNotEmpty()
println(listOf(1, 2, 3).secondOrNull)  // 2

Логические свойства-расширения

Создавайте понятные логические свойства для проверки типов.
val Any.isString: Boolean get() = this is String
val String.hasDigits: Boolean get() = any { it.isDigit() }
val Int.isPositive: Boolean get() = this > 0
println(42.isPositive)        // true
println("abc123".hasDigits)   // true

Свойства-расширения и функции-расширения

Используйте свойство, если вычисление простое и представляет характеристику объекта. Используйте функцию, если ей нужны параметры или если она имеет побочные эффекты.
// Property: stateless, simple characteristic
val String.isEmail: Boolean get() = '@' in this
// Function: has parameters
fun String.padCenter(width: Int) = padStart((length + width) / 2)

Расширение сопутствующего объекта

Добавляйте свойства-расширения к сопутствующим объектам.
data class Color(val r: Int, val g: Int, val b: Int) {
    companion object
}
val Color.Companion.RED get() = Color(255, 0, 0)
val Color.Companion.WHITE get() = Color(255, 255, 255)
println(Color.RED)  // Color(r=255, g=0, b=0)

Контекстные свойства-расширения

Свойства-расширения, определённые внутри класса, применяются только внутри области действия этого класса.
class Formatter {
    val Int.formatted: String
        get() = "%,d".format(this)
    fun format(n: Int) = n.formatted
}
println(Formatter().format(1000000))  // 1,000,000

Использование расширений для DSL

Свойства-расширения лежат в основе проектирования Kotlin DSL.
val Int.dp: Float get() = this * 2.5f
val Float.sp: Float get() = this * 1.0f
// In DSL context:
view.setPadding(16.dp.toInt())

Обобщённые свойства-расширения

Свойства-расширения могут иметь параметры типа.
val <T> List<T>.head: T?
    get() = firstOrNull()
val <T> List<T>.tail: List<T>
    get() = drop(1)
println(listOf(1,2,3).head)  // 1
println(listOf(1,2,3).tail)  // [2, 3]

Быстрая проверка

Могут ли свойства-расширения иметь резервные поля в Kotlin?

Итоги

Свойства-расширения добавляют вычисляемые характеристики к типам без резервных полей. Используйте их для простых вычислений без состояния. У изменяемых свойств-расширений могут быть сеттеры. Они отлично подходят для DSL и плавных API. Далее: расширения с областью действия и расширения сопутствующих объектов!
Можно начать бесплатно

Изучай Kotlin с ИИ-репетитором — бесплатно

Пиши и запускай код прямо в браузере, получай мгновенную помощь от ИИ-репетитора 24/7 и продолжи учиться на сайте или в приложении.

Курсы
51
Уроки
203

Часто задаваемые вопросы

Урок «Свойства-расширения и вычисляемые расширения» бесплатный?

Да — полный текст урока «Свойства-расширения и вычисляемые расширения» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Kotlin Academy, подпишись на CoddyKit PRO. Курс Kotlin Academy содержит 4 уроков всего.

Чему я научусь в уроке «Свойства-расширения и вычисляемые расширения»?

Добавляйте вычисляемые свойства к существующим классам без создания подклассов. Ты практикуешь Kotlin Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Kotlin Academy?

Предыдущий опыт не требуется. Kotlin Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.

Сколько времени занимает урок «Свойства-расширения и вычисляемые расширения»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Kotlin Academy?

Да. Каждый урок Kotlin Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Функции-расширения: синтаксис и правила диспетчеризации
  2. Свойства-расширения и вычисляемые расширения
  3. Расширения областей видимости и companion-расширения
  4. Практические расширения: помощники для Context, View и String
← Назад к Kotlin Academy