Запечатанный классом

Kotlin Vocabulary - Запечатанные классы

Часто нам нужно представить ограниченный набор возможностей; веб-запрос либо выполнен успешно, либо не выполнен, Userможет быть только Pro-User или стандартный пользователь.

Чтобы смоделировать это, мы могли бы использовать enum, но это имеет ряд ограничений. Классы Enum допускают только один экземпляр каждого значения и не могут кодировать дополнительную информацию о каждом типе, например, Errorслучае, имеющем связанное Exceptionсвойство.

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

Основы закрытых классов

Как и абстрактные классы, запечатанные классы позволяют вам представлять иерархии. Дочерние классы могут быть классами любого типа: классом данных, объектом , обычным классом или даже другим закрытым классом. В отличие от абстрактных классов, вы должны определять эти иерархии в том же файле или как вложенные классы.

// Result.kt
sealed class Result<out T : Any> {
    data class Success<out T : Any>(val data: T) : Result<T>()
    data class Error(val exception: Exception) : Result<Nothing>()
}

Cannot access ‘<init>’: it is private in Result

Часто мы хотим обрабатывать все возможные типы:

when(result) {
    is Result.Success -> { }
    is Result.Error -> { }
}

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

val action = when(result) {
    is Result.Success -> { }
    is Result.Error -> { }
}

Чтобы получить это отличное преимущество, даже когда мы используем when в качестве оператора, добавьте это свойство вспомогательного расширения:

val <T> T.exhaustive: T
    get() = this

when(result){
    is Result.Success -> { }
    is Result.Error -> { }
}.exhaustive

Поскольку все подтипы запечатанного класса известны, IDE может заполнить для нас все возможные ветви оператора when:

Эта функция действительно выделяется более сложными иерархиями закрытых классов, поскольку IDE может распознавать все ветви:

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

      

Под капотом

Так что же заставляет закрытые классы вести себя так, как они? Посмотрим, что происходит в декомпилированном Java-коде:

sealed class Result
data class Success(val data: Any) : Result()
data class Error(val exception: Exception) : Result()
@Metadata(
…
d2 = {“Lio/testapp/Result;”, “T”, “”, “()V”, “Error”, “Success”, “Lio/testapp/Result$Success;”, “Lio/testapp/Result$Error;” …}
)
public abstract class Result {
    private Result() {}
    // $FF: synthetic method
    public Result(DefaultConstructorMarker $constructor_marker) {
        this();
    }
}

ResultРеализуется как абстрактный класс с двумя конструкторами:

  • Частный конструктор по умолчанию
  • Синтетический конструктор, который может использоваться только компилятором Kotlin.

public final class Success extends Result {
    @NotNull
    private final Object data
    
    public Success(@NotNull Object data) {
      
       super((DefaultConstructorMarker)null);
       this.data = data;
    }

Suggested posts

Переход с Dagger2 на Hilt в многомодульном проекте

Переход с Dagger2 на Hilt в многомодульном проекте

Пошаговое руководство по переходу с Dagger на Hilt в многомодульном проекте. Структура проекта Для визуализации проекта он содержит несколько модулей NetworkModule, StorageModule, CommonModule, FeatureModule и т. д.

Андроид | Gboard был обновлен с новым макетом для планшетов

Google обновил раскладку своей клавиатуры как раз к запуску Pixel Fold и Pixel Tab.

Андроид | Gboard был обновлен с новым макетом для планшетов

Google недавно обновил свое приложение клавиатуры Gboard для Android, включив новый макет, оптимизированный для планшетов. Сегодня утром я заметил, что мне трудно печатать, и при дальнейшем осмотре я понял, что клавиатура была заменена.

Related posts

Создание безопасной рабочей среды

Создание безопасной рабочей среды

«Он защитит меня, когда я в опасности. Он спрячет меня в своей палатке.

Как спасти планету и заработать деньги

Как спасти планету и заработать деньги

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

Обучение на рабочей неделе важнее, чем вы думаете

Обучение на рабочей неделе важнее, чем вы думаете

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

Больше никаких паролей — как пароли заменят ваш пароль

Больше никаких паролей — как пароли заменят ваш пароль

Во избежание двусмысленности будут использоваться следующие термины; Аутентификатор; Мобильный телефон, используемый для входа на веб-сайт; веб-сайт или приложение, которое пользователь использует для выполнения запроса на вход в систему; Поставщик, предоставляющий данную услугу, например