Kotlin 中的 Getter 和 Setter

问题描述 投票:0回答:9

例如,在 Java 中,我可以自己编写 getter(由 IDE 生成)或使用像 lombok 中的 @Getter 这样的注释 - 这非常简单。

Kotlin 默认有 getter 和 setter。 但我不明白如何使用它们。

我想要做到这一点,可以说 - 类似于 Java:

private val isEmpty: String
        get() = this.toString() //making this thing public rises an error: Getter visibility must be the same as property visibility.

那么吸气剂是如何工作的呢?

kotlin getter-setter
9个回答
213
投票

Getter 和 Setter 在 Kotlin 中自动生成。如果你写:

val isEmpty: Boolean

相当于下面的Java代码:

private final Boolean isEmpty;

public Boolean isEmpty() {
    return isEmpty;
}

在您的情况下,私有访问修饰符是多余的 - isEmpty 默认情况下是私有的,只能由 getter 访问。当您尝试获取对象的 isEmpty 属性时,您实际上调用了 get 方法。为了更多地了解 Kotlin 中的 getter/setter:下面的两个代码示例是相同的:

var someProperty: String = "defaultValue"

var someProperty: String = "defaultValue"
    get() = field
    set(value) { field = value }

我还想指出 getter 中的

this
不是你的属性 - 它是类实例。如果您想在 getter 或 setter 中访问字段的值,您可以使用保留字
field

val isEmpty: Boolean
  get() = field

如果您只想在公共访问中拥有 get 方法 - 您可以编写以下代码:

var isEmpty: Boolean
    private set 

由于 set 访问器附近的私有修饰符,您只能在对象内部的方法中设置此值。


36
投票

有关属性访问器可见性修饰符的规则如下:

  • var
    val
    属性的Getter可见性应该与属性的可见性完全相同,因此只能显式复制属性修饰符,但这是多余的:

    protected val x: Int
        protected get() = 0 // No need in `protected` here.
    
  • var
    属性的设置器可见性应该与属性可见性相同或更少:

    protected var x: Int get() = 0 private set(x: Int) { } // Only `private` and `protected` are allowed.
    
    
在 Kotlin 中,属性始终通过 getter 和 setter 进行访问,因此无需像 Java 那样使用

private

 访问器创建属性 
public
 —— 
其支持字段(如果存在) 已经是私有的。因此,属性访问器上的可见性修饰符仅用于降低 setter 可见性:

  • 对于具有支持字段和默认访问器的属性:

    var x = 0 // `public` by default private set
    
    
  • 对于没有支持字段的属性:

    var x: Int // `public` by default get() = 0 protected set(value: Int) { }
    
    

27
投票
1) Kotlin 中

property

 
setter
 的默认示例 
getterfirstName
 

class Person { var firstName: String = "" get() = field // field here ~ `this.firstName` in Java or normally `_firstName` is C# set(value) { field = value } }

使用

val p = Person() p.firstName = "A" // access setter println(p.firstName) // access getter (output:A)

如果您的setter

getter
与上面
完全相同,您可以将其删除,因为它是不必要的

2) 自定义 setter 和 getter 示例。

const val PREFIX = "[ABC]" class Person { // set: if value set to first name have length < 1 => throw error else add prefix "ABC" to the name // get: if name is not empty -> trim for remove whitespace and add '.' else return default name var lastName: String = "" get() { if (!field.isEmpty()) { return field.trim() + "." } return field } set(value) { if (value.length > 1) { field = PREFIX + value } else { throw IllegalArgumentException("Last name too short") } } }

使用

val p = Person() p.lastName = "DE " // input with many white space println(p.lastName) // output:[ABC]DE. p.lastName = "D" // IllegalArgumentException since name length < 1

更多 我从 Java 开始学习 Kotlin,所以我对
field

property
 感到困惑,因为在 Java 中没有 
property
经过一番搜索,我发现 Kotlin 中的
field
property
 看起来像 C#(
字段和属性有什么区别?

这里有一些相关的帖子,讨论了 Java 和 Kotlin 中的

field

property

java有类似C#的属性吗?
https://blog.kotlin-academy.com/kotlin-programmer-dictionary-field-vs-property-30ab7ef70531

如果我错了,请纠正我。希望有帮助


10
投票
kotlin 中的 getter 默认是 public,但你可以将 setter 设置为 private,并使用类中的一个方法来设置值。像这样。

/** * Created by leo on 17/06/17.*/ package foo class Person() { var name: String = "defaultValue" private set fun foo(bar: String) { name = bar // name can be set here } } fun main(args: Array<String>) { var p = Person() println("Name of the person is ${p.name}") p.foo("Jhon Doe") println("Name of the person is ${p.name}") }
    

9
投票
如果您有 Var,那么您可以:

var property: String = "defVal" get() = field set(value) { field = value }
但是对于 Val 来说,一旦分配就无法设置它,因此不会有 setter 块:

val property: String = "defVal" get() = field
或者如果你不想要二传手那么:

val property: String = "defVal" private set
    

6
投票
您可以查看本教程以获取更多信息:

又一个面向 Android 开发者的 Kotlin 教程

属性

在 Kotlin 世界中,类不能有字段,只有属性。变量 与 val 相比,关键字告诉我们该属性是可变的。让我们 看一个例子:

class Contact(var number: String) { var firstName: String? = null var lastName: String? = null private val hasPrefix : Boolean get() = number.startsWith("+") }
  
  
代码不多,但背后发生了很多事情 场景。

我们将一步一步地进行。首先,我们创建了一个 公开期末班联系方式。

这是我们必须面对的首要规则:如果没有特别说明, 默认情况下,类是公共的和最终的(顺便说一句,对于 类方法)。如果要继承类,则标记为open 关键字。


0
投票
这是一个真实的 Kotlin getter 和 setter 示例(查看更多详细信息

此处):

// Custom Getter 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 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"
    

0
投票
有点不同意@Cortwave 的最佳答案。

Kotlin成员字段默认情况下是最终的,不是私有的。您必须编写私有修饰符才能将其封装在类中。 我在这里寻找的答案是 kotlin 是否自动生成私有成员字段的 getter 和 setter 还是你必须自己生成? Android Studio 中的简单实现表明您需要自己编写它。


0
投票
© www.soinside.com 2019 - 2024. All rights reserved.