如何让一个数据类在Kotlin中实现接口/扩展超类属性?

19

我有几个数据类,其中包括一个var id: Int?字段。我想在接口超类中表达这一点,并使数据类扩展它并在构造时设置此id。但如果我尝试这样做:

interface B {
  var id: Int?
}

data class A(var id: Int) : B(id)

它抱怨我正在覆盖id字段,而事实上我的确是这样做了哈哈..

Q: 在这种情况下,我该如何让数据类A在构造时接受一个id,并设置在接口父类中声明的那个id

2个回答

21

实际上,你还不需要一个抽象类(abstract class)。你可以直接重写(interface)的属性,例如:

interface B {
    val id: Int?
}

//           v--- override the interface property by `override` keyword
data class A(override var id: Int) : B

一个接口没有构造函数,因此您无法使用super(..)关键字调用构造函数,但是您可以使用抽象类。然而,数据类不能在其主构造函数中声明任何参数,因此它将覆盖超类的字段,例如:

//               v--- makes it can be override with `open` keyword
abstract class B(open val id: Int?)

//           v--- override the super property by `override` keyword
data class A(override var id: Int) : B(id) 
//                                   ^
// the field `id` in the class B is never used by A

// pass the parameter `id` to the super constructor
//                            v
class NormalClass(id: Int): B(id)

1
@EdyBourne 一点也不。事实上,我对问题中的“超类”一词感到困惑,并在第一次滥用“抽象类”。直到我写下答案才意识到让data class扩展class存在一些问题。所以我改变了思路,最终发现你只是想要实现接口getters/setters而已。 - holi-java
open val - is that right? Seems like protected final - Abhijit Sarkar
@Abhijit Sarkar您好,没有问题。因为它断言其getter可以被覆盖,而且它的后端字段也是final - holi-java
那么它会被翻译成一个带有protected getter的private final字段吗? - Abhijit Sarkar
2
@Abhijit Sarkar 是的,但 getter 的可见性没有改变,它是公共的。 - holi-java

0
interface B {
    var id: Int?
}

data class A(override var id: Int?) : B

var a1:A = A(1)
var a2:A = A(null)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接