Kotlin - 理解Getter和Setter

14

Kotlin自动生成getter和setter,但我从未引用它们?同时,什么是Kotlin中编写自定义getter/setter的正确方式?当我说myObj.myVar = 99时,我感觉像是直接访问myObj的公共字段myVar?这里实际上发生了什么?


可能是 Kotlin 中的 Getters 和 Setters 的重复问题。 - Bharatesh
2个回答

23

这个问题已经在几个地方得到了解答,但我想为那些从Java / C# / C / C ++转换到Kotlin,并且有与我相同的疑问的人分享一个具体的例子:

我很难理解在Kotlin中getter和setter如何工作,特别是因为它们从未被显式调用(就像在Java中一样)。因此,我感到不舒服,因为看起来我们只是直接引用vars / vals作为字段。所以我进行了一项小实验,以证明这不是事实,并且实际上是在访问变量/值时在Kotlin中调用了隐式(自动生成的)或显式getter / setter。区别在于,您不需要显式请求默认的getter / setter。

来自文档 - 声明属性的完整语法如下:

var <propertyName>: <PropertyType> [= <property_initializer>]
   [<getter>]
   [<setter>]

我的例子是

class modifiersEg {

/** this will not compile unless:
 *      - we assign a default here
 *      - init it in the (or all, if multiple) constructor
 *      - insert the lateinit keyword    */
var someNum: Int?
var someStr0: String = "hello"
var someStr1: String = "hello"
    get() = field  // field is actually this.someStr1, and 'this' is your class/obj instance
    set(value) { field = value }

// kotlin actually creates the same setters and getters for someStr0
// as we explicitly created for someStr1

var someStr2: String? = "inital val"
    set(value) { field = "ignore you" }

var someStr3: String = "inital val"
    get() = "you'll never know what this var actually contains"

init {
    someNum = 0

    println(someStr2) // should print "inital val"

    someStr2 = "blah blah blah"
    println(someStr2) // should print "ignore you"

    println(someStr3) // should print "you'll never know what this var actually contains"
}

我希望这能帮助其他一些人更好地理解。


我知道这可能不太适合初学者,但是对于一些更复杂的属性相关特性,比如委托属性,我强烈建议使用Kotlin字节码检查器。 - daemontus
对于某些名为 someStr0 的属性,其 getters 和 setters 的可见性范围是什么?在此示例中,所有属性都是公共的(默认)。如果我有私有属性,这个示例会起作用吗?作为一个 Java 开发者,我习惯了这种方式。 - Kumar Sambhav
如何使用getter和setter来访问私有变量。 - viper
如果将变量设为私有,它是否仍会生成getter和setter? - AtomicallyBeyond

0

以下是一些自定义 getter 和 setter 的实际应用示例。您可以在此处查看更多

// Custom getter example
val friendlyDescription get(): String {
    val isNeighborhood = district != null
    var description = if (isNeighborhood) "Neighborhood" else "City"
    description += " in"
    if (isNeighborhood) {
        description += " $city,"
    }
    province?.let {
        if (it.isNotEmpty()) {
            description += " $it,"
        }
    }
    description += " $country"
    return description
}

print(myLocation.friendlyDescription) // "Neighborhood in Denver, Colorado, United States"

// Custom setter example
enum class SearchResultType {
    HISTORY, SAVED, BASIC
}

private lateinit var resultTypeString: String

var resultType: SearchResultType
    get() {
        return enumValueOf(resultTypeString)
    }
    set(value) {
        resultTypeString = value.toString()
    }

result.resultType = SearchResultType.HISTORY
print(result.resultTypeString) // "HISTORY"


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