← Назад к вопросам

Расскажи про все виды классов в Kotlin

1.0 Junior🔥 242 комментариев
#Kotlin основы

Комментарии (2)

🐱
deepseek-v3.2PrepBro AI6 апр. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Классы в Kotlin: полная классификация

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

1. Обычный (classic) класс

Это базовый, наиболее распространённый тип класса. Объявляется ключевым словом class. Может содержать первичный или вторичные конструкторы, свойства, методы, инициализаторы. По умолчанию все классы в Kotlin являются финальными (final) — их нельзя наследовать без явного разрешения.

class Person(
    val name: String, // свойство, объявленное в первичном конструкторе
    var age: Int
) {
    init {
        require(age >= 0) { "Возраст не может быть отрицательным" }
    }
    
    fun celebrateBirthday() {
        age++
        println("$name теперь $age лет")
    }
}

2. Абстрактный класс (abstract class)

Не может быть инстанциирован напрямую. Служит базовым классом для наследования. Может содержать как абстрактные члены (без реализации), так и конкретные (с реализацией). Используется для моделирования общих характеристик и поведения группы объектов.

abstract class Shape(val color: String) {
    abstract fun area(): Double // абстрактный метод
    
    fun describe() { // конкретный метод
        println("Фигура цвета $color с площадью ${area()}")
    }
}

class Circle(color: String, val radius: Double) : Shape(color) {
    override fun area(): Double = Math.PI * radius * radius
}

3. Data class (класс данных)

Специальный класс, основной целью которого является хранение данных. Компилятор автоматически генерирует полезные методы: equals(), hashCode(), toString(), copy(), а также функции-компоненты componentN(). Должен иметь как минимум один параметр в первичном конструкторе, и все параметры должны быть объявлены как val или var.

data class User(
    val id: Long,
    val username: String,
    val email: String
)

// Автоматически получаем:
// equals()/hashCode(), toString("User(id=1, username=john, email=john@test.com)"),
// copy(), component1() = id, component2() = username и т.д.

4. Sealed class (изолированный/запечатанный класс)

Представляет ограниченную иерархию классов. Все подклассы sealed-класса должны быть объявлены в том же файле (начиная с Kotlin 1.5, разрешено в одном пакете). Это делает их идеальными для моделирования алгебраических типов данных и безопасной обработки всех возможных вариантов в when-выражениях.

sealed class Result<out T> {
    data class Success<T>(val data: T) : Result<T>()
    data class Error(val exception: Exception) : Result<Nothing>()
    object Loading : Result<Nothing>()
}

fun handleResult(result: Result<String>) {
    when (result) {
        is Result.Success -> println("Данные: ${result.data}")
        is Result.Error -> println("Ошибка: ${result.exception.message}")
        Result.Loading -> println("Загрузка...")
    }
}

5. Inner class (внутренний класс) и Nested class (вложенный класс)

  • Nested class (объявляется просто как class внутри другого класса) — статический по своей природе. Не имеет доступа к членам внешнего класса.
  • Inner class (объявляется с ключевым словом inner) — содержит неявную ссылку на экземпляр внешнего класса и может обращаться к его членам.
class Outer {
    private val outerProperty = "Outer"
    
    class Nested { // Аналог static class в Java
        fun foo() = "Nested не видит outerProperty"
    }
    
    inner class Inner {
        fun bar() = "Inner видит $outerProperty"
    }
}

6. Enum class (перечисление)

Специальный тип класса, представляющий фиксированный набор именованных констант. Каждая константа — это отдельный экземпляр enum-класса. Может содержать свойства, методы и реализовывать интерфейсы.

enum class Direction(val degrees: Int) {
    NORTH(0),
    EAST(90),
    SOUTH(180),
    WEST(270);
    
    fun opposite(): Direction = when (this) {
        NORTH -> SOUTH
        EAST -> WEST
        SOUTH -> NORTH
        WEST -> EAST
    }
}

7. Inline class (значимый класс)

Начиная с Kotlin 1.5 (ранее experimental как inline class, сейчас стабилен как value class). Предназначен для обёртки примитивных типов или других данных без накладных расходов на выделение памяти в рантайме (компилятор старается использовать базовый тип напрямую). Идеально подходит для предотвращения логических ошибок за счёт типобезопасности.

@JvmInline
value class Password(private val s: String) // Обёртка для строки пароля

fun login(password: Password) { ... }
// При компиляции часто используется String, но в коде тип Password
// защищает от передачи обычной строки по ошибке.

8. Object declaration (объявление объекта) и Companion object (спутник)

  • Object declaration (object) реализует шаблон Singleton — класс с единственным экземпляром, создаваемым потокобезопасно при первом обращении.
  • Companion object — объект, объявленный внутри класса с ключевым словом companion. Его члены доступны по имени класса. Может реализовывать интерфейсы и иметь имя.
object DatabaseManager { // Singleton
    fun connect() { ... }
}

class MyFragment {
    companion object { // Спутник
        const val TAG = "MyFragment"
        fun newInstance() = MyFragment()
    }
}
// Использование: DatabaseManager.connect(), MyFragment.TAG, MyFragment.newInstance()

9. Functional (SAM) interface (функциональный интерфейс)

Интерфейс с одним абстрактным методом (Single Abstract Method). Может быть реализован через лямбда-выражение. Помечается ключевым словом fun.

fun interface OnClickListener {
    fun onClick(view: View)
}

// Реализация через лямбду
val listener = OnClickListener { println("Клик!") }

Ключевые выводы

Разнообразие классов в Kotlin позволяет точно моделировать предметную область, выбирая наиболее подходящую семантику:

  • Используйте data class для DTO, POJO, моделей.
  • Sealed class идеальны для выражения состояний и результатов операций.
  • Value class повышают типобезопасность без производительности.
  • Abstract class и интерфейсы (хотя технически интерфейс — не класс) служат для построения иерархий и полиморфизма.
  • Object реализует паттерн Singleton идиоматично.

Этот богатый инструментарий, в сочетании с принципами ООП и функционального программирования, делает Kotlin исключительно мощным языком для разработки под Android и не только.