Skip to content

Latest commit

 

History

History
57 lines (45 loc) · 4.44 KB

sealed-classes.md

File metadata and controls

57 lines (45 loc) · 4.44 KB
type layout category title url
doc
reference
Classes and Objects
Изолированные классы

Изолированные классы

Изолированные классы используются для отражения ограниченных иерархий классов, когда значение может иметь тип только из ограниченного набора, и никакой другой. Они являются, по сути, расширением enum-классов: набор значений enum типа также ограничен, но каждая enum-константа существует только в единственном экземпляре, в то время как наследник изолированного класса может иметь множество экземпляров, которые могут нести в себе какое-то состояние.

Чтобы описать изолированный класс, укажите модификатор sealed перед именем класса. Изолированный класс может иметь наследников, но все они должны быть объявлены в том же файле, что и сам изолированный класс. (До версии Kotlin 1.1 правила были ещё более строгими: классы должны были быть вложены в объявлении изолированного класса).

sealed class Expr
data class Const(val number: Double) : Expr()
data class Sum(val e1: Expr, val e2: Expr) : Expr()
object NotANumber : Expr()

fun eval(expr: Expr): Double = when (expr) {
    is Const -> expr.number
    is Sum -> eval(expr.e1) + eval(expr.e2)
    NotANumber -> Double.NaN
}

(Пример выше использует одну новую возможность Kotlin 1.1: расширение классов, включая изолированные, классами данных) Обратите внимание, что классы, которые расширяют наследников изолированного класса (непрямые наследники) могут быть помещены где угодно, не обязательно в том же файле.

Ключевое преимущество от использования изолированных классов проявляется тогда, когда вы используете их в выражении when. Если возможно проверить что выражение покрывает все случаи, то вам не нужно добавлять else.

fun eval(expr: Expr): Double = when(expr) {
    is Expr.Const -> expr.number
    is Expr.Sum -> eval(expr.e1) + eval(expr.e2)
    Expr.NotANumber -> Double.NaN
    // оператор `else` не требуется, потому что мы покрыли все возможные случаи
}