【问题标题】:Benefits of declaring a sealed class as object将密封类声明为对象的好处
【发布时间】:2019-12-21 21:59:54
【问题描述】:

上下文

我有这个sealed class 和它的每个孩子:

sealed class Section

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

但我对每个类声明都收到警告:

密封的子类没有状态,也没有覆盖等于

这建议我将它们声明为:

object ProfileSection : Section()

问题

  • 这样做的目的是什么?
  • 有什么好处?
  • 为什么我要把它们写成object 而不是class

【问题讨论】:

  • 你为什么首先使用密封类而不是枚举?

标签: kotlin sealed-class


【解决方案1】:

首先让我解释一下密封类的目的是什么。 the official documentation 的第一句话说:

密封类用于表示受限制的类层次结构,当一个值可以具有有限集合中的一种类型,但不能具有任何其他类型时。 从某种意义上说,它们是枚举类的扩展。

我相信您已经熟悉枚举,它们是一种特殊类型,可以将变量定义为预定义常量之一,并且每个都可以存储一些额外的数据。每个常数只有一个实例。至此,您可能已经注意到这个单一实例和数据保存的东西听起来像 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
}

所以最后回答你原来的问题:

这样做的目的是什么?

与枚举常量相同。如果您不需要在“常量”中存储状态并且只需要带有可选静态数据的命名类型,那么请使用对象。

有什么好处?

为什么我应该把它们写成对象而不是类?

如果你不需要你的“常量”来拥有一个状态,那么每次你想使用它时创建一个不同的实例只是浪费内存。

【讨论】:

  • 感谢您的回答,它真的很有帮助和解释性。
猜你喜欢
  • 2023-01-26
  • 2010-11-19
  • 2021-06-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-10
  • 2013-03-07
相关资源
最近更新 更多