Особенности sealed
Sealed классы и интерфейсы в Kotlin предоставляют способ ограничить иерархию классов, что позволяет вам четко контролировать, какие подклассы могут быть созданы. Это особенно полезно при работе с исчерпывающими when-выражениями, где компилятор может проверять, все ли возможные случаи рассмотрены.
Ограничение подклассов: Подклассы sealed класса или интерфейса могут быть объявлены только в том же файле, что и сам sealed класс или интерфейс. Это ограничение позволяет компилятору знать все возможные подклассы, что упрощает обработку в when-выражениях.
Исчерпывающее when-выражение: Благодаря знанию всех возможных подклассов, компилятор может обеспечить, что вы рассматриваете все случаи в when-выражении, избегая ошибок времени выполнения.
Поддержка данных и вложенных типов: Sealed классы могут содержать объекты данных, которые позволяют создавать удобные представления состояний с различными параметрами.
Под капотом sealed классы компилируются в абстрактные классы, и каждый подкласс хранится в том же файле. Компилятор добавляет проверки для обеспечения того, что подклассы не могут быть объявлены вне файла, содержащего sealed класс или интерфейс.
sealed class Result {
data class Success(val data: String) : Result()
data class Error(val exception: Throwable) : Result()
object Loading : Result()
}
fun handleResult(result: Result) {
when (result) {
is Result.Success -> println("Data: ${result.data}")
is Result.Error -> println("Error: ${result.exception.message}")
is Result.Loading -> println("Loading...")
}
}
// Пример скомпилированного кода на Java для sealed класса Result
public abstract class Result {
private Result() {}
public static final class Success extends Result {
private final String data;
public Success(String data) {
this.data = data;
}
public String getData() {
return data;
}
}
public static final class Error extends Result {
private final Throwable exception;
public Error(Throwable exception) {
this.exception = exception;
}
public Throwable getException() {
return exception;
}
}
public static final class Loading extends Result {
public static final Loading INSTANCE = new Loading();
private Loading() {}
}
}