Confused about interfaces

huangapple go评论49阅读模式
英文:

Confused about interfaces

问题

这段代码在我仅使用对象时有效,但是当我使用 val 而不是对象时,IDE 报错:类 'Success' 不是抽象类,也没有实现抽象成员。任何帮助将不胜感激。

这段代码有效:

    data class Success(val photos: List<MarsPhoto>) : MarsUiState
    object Error : MarsUiState
    object Loading: MarsUiState
}

这段代码无效:

    data class Success(val photos: List<MarsPhoto>) : MarsUiState
    object Error : MarsUiState
    val Loading: MarsUiState
}
英文:

This code works when I only use objects, however when I use a val instead of an object the IDE gives an error : Class 'Success' is not abstract and does not implement abstract member. Any help would be appreciated.

This works fine:

    data class Success(val photos: List&lt;MarsPhoto&gt;) : MarsUiState
    object Error : MarsUiState
    object Loading: MarsUiState
}

This doesn't

sealed interface MarsUiState {
    data class Success(val photos: List&lt;MarsPhoto&gt;) : MarsUiState
    object Error : MarsUiState
    val Loading: MarsUiState
} 

答案1

得分: 2

val 在接口类型上定义了一个属性,而 object 定义了一个新的类型,而不是一个变量/属性。

实际上,关于对象可能会让你感到困惑的是,它们的名称不仅定义了一个类型,还定义了一种访问该类型唯一值的方式。因此,当将 Loading 声明为 object 时,MarsUiState.Loading 既是一种类型又是一个值,可以在 Kotlin 语法中用于期望类型的地方(例如函数定义的参数类型或函数的返回类型),同时也可以用在期望表达式/值的地方,比如赋值的右侧(val x = expression)或函数调用的参数(myFun(expression))。

在这里使用 val 意味着 MarsUiState 具有一个名为 Loading 的属性,因此 MarsUiState 的任何实例都必须具有该属性的值(而 Success 子类型不符合这一点,因此会导致错误)。但这根本没有意义。

这里的要点是说,MarsUiState 类型的实例可以是三个子类型之一:SuccessErrorLoading。因此,这三个东西也必须是类型(可以是类或对象 - 也可以认为对象是一种类,只不过它们只有一个实例)。

英文:

val defines a property on the interface type, while object defines a new type, not a variable/property.

Actually, the thing that might confuse you about objects is that their name not only defines a type, but also a way to access the only value of that type. So when Loading is declared as an object, MarsUiState.Loading is both a type and a value, and can be used in the Kotlin syntax in places that expect a type (like the parameter types in a function definition, or the return type of a function), and also in places that expect an expression/value, like the right-hand side of an assignment (val x = expression), or the argument of a function call (myFun(expression)).

Using val here would mean that the MarsUiState has a property named Loading and thus any instance of MarsUiState has to have a value for that property (and the Success subtype doesn't respect that, so you get an error). But that doesn't make any sense anyway.

The point here is to say that instances of the MarsUiState type can be of one of 3 subtypes: either Success, Error, or Loading. So all those 3 things must be types too (either classes or objects - which are kinda classes too, they just have only one instance).

huangapple
  • 本文由 发表于 2023年6月13日 16:18:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/76462959.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定