使用主构造函数时的Kotlin getter / setter

29

这个例子来自我正在学习的Kotlin课程:

class Car {
    var speed: Int = 0
        get() = field 
        set(value) {
            field = value
        }
}

如果我喜欢使用这样的主构造函数:

class Car(var speed: Int)

在这种情况下,我该如何编写getter/setter?

3个回答

44

构造函数内部不可以编写getter/setter,您可以执行以下操作:

  1. 在类内部创建一个变量,其值从构造函数中获得。
class Car(speed: Int) {
    var speed = speed
        get() = field 
        set(value) {
            field = value
        }
}
  1. 使用@JvmField注解来防止编译器自动生成getter/setter方法,并手动实现它们
class Car(@JvmField private var speed: Int) {
    fun getSpeed() = speed
    fun setSpeed(value: Int) { speed = value }
}

2
你需要一个私有的后备字段,否则编译器会抱怨说:“在此处不允许初始化程序,因为该属性没有后备字段”。 - Steven Jeuris
1
我对JVM/Kotlin互操作还很陌生,但似乎“JvmField对私有属性没有影响”,据我理解,第二个示例应该删除“private”。 - Lyoneel
1
对于仍然对上述方法#1感到困惑的任何人:关键在于您必须删除val/var。因此,class Car(speed: Int)而不是class Car(var speed : Int),后者会创建重复且冲突的声明。 - Brian McFarland

7
您可以在构造函数中使用值初始化您的属性:
class Car(speed: Int) {
    var speed: Int = speed
        get() = field
        set(value) {
            field = value
        }
}

1
属性的语法 -
var <propertyName>[: <PropertyType>] [= <property_initializer>]
    [<getter>]
    [<setter>]

这里,属性初始化器、getter和setter是可选的。如果可以从初始化器中推断出属性类型,我们也可以省略属性类型。 只读或不可变属性声明的语法与可变属性声明的语法有两个不同之处: 以val开头而不是var,并且不允许设置器。
在kotlin中,val仅用于读取,表示getter,var用于非getter()setter()
class Company {
var name: String = "Defaultvalue"
}

上面的代码与下面的代码等效。
class Company {
    var name: String = "defaultvalue"
        get() = field                     // getter
        set(value) { field = value }      // setter
}

如果您想在Car类中保存数据,也可以使用Kotlin的data class。这样,您就不需要定义getter和setter了。

data class Car(var speed: Int)

更多信息请查看https://kotlinlang.org/docs/reference/properties.html#getters-and-setters


1
所以你不需要为非“data”类定义getter和setter。 - Alexey Romanov
是的,在 Kotlin 中,您不需要手动定义 getter 和 setter。在 Kotlin 中,getter 和 setter 是可选的。 - Krishna Sony

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