Преимущества объявления закрытого класса как объекта - PullRequest
0 голосов
/ 22 декабря 2019

Контекст

У меня есть это sealed class и каждый из его дочерних элементов:

sealed class Section

class SearchSection : Section()
class FavoritesSection : Section()
class RecommendationsSection : Section()
class ProfileSection : Section()

Но я получаю предупреждение по каждому объявлению класса:

Запечатанные подклассы не имеют состояния и не имеют перезаписи равных

Что предлагает мне объявить их как:

object ProfileSection : Section()

Вопрос

  • Какова цельэтого?
  • Каковы преимущества?
  • Почему я должен написать их как object, а не class?

1 Ответ

2 голосов
/ 22 декабря 2019

Прежде всего позвольте мне объяснить, какова цель закрытых классов. Самые первые предложения в официальной документации гласят:

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

Я уверен, что вы уже знакомы с перечислениями, это особый тип, который позволяет переменной бытьопределяется как одна из предопределенных констант, и каждая из них может хранить некоторые дополнительные данные. И есть только один экземпляр каждой константы. К этому моменту вы, возможно, заметили, что этот отдельный экземпляр и материал для хранения данных звучат как объекты Kotlin. Получается, что этот перечислимый класс:

enum class Type(val value: String) {
    A("a"),
    B("b")
}

эквивалентен этому запечатанному классу:

sealed class Type(val value: String) {
    object A : Type("a")
    object B : Type("b")
}

(на самом деле константы перечисления являются объектами в Kotlin).

Что делает запечатанные классы особенными, так это то, что они позволяют вам определять «константы», используя классы вместо объектов, чтобы они могли иметь более одного экземпляра и, следовательно, сохранять фактическое состояние, например:

sealed class ApiReponse

data class Success(val data: Data) : ApiResponse()
object Error : ApiResponse()

fun getResponse(): ApiResponse {
    ...
    return if (apiCall.isSuccessful) Success(apiCall.data) else Error
}

Итак, наконец,ответьте на свои первоначальные вопросы:

Какова цель этого?

То же, что и константы перечисления. Если вам не нужно хранить состояние внутри вашей «константы» и вам нужен только именованный тип с необязательными статическими данными, тогда идите с объектом.

Каковы преимущества?

Почему я должен писать их как объект, а не как класс?

Если вам не нужна ваша «константа», чтобы иметь состояние, это просто пустая трата памяти насоздавайте новый экземпляр каждый раз, когда хотите его использовать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...