科特林的吸气剂和二传手


86

例如,在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.

那么吸气剂如何工作?

Answers:


142

吸气和吸气器是在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 }

我还要指出,this在吸气剂中,不是您的属性-它是类实例。如果要在getter或setter中访问字段的值,则可以field为其使用保留字:

val isEmpty: Boolean
  get() = field

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

var isEmpty: Boolean
    private set 

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


16
In your case the private access modifier is redundant怎么样?Kotlin doc的默认修饰符是public。kotlinlang.org/docs/reference/visibility-modifiers.html

@Nothing是的,似乎是公共场所,但是在
后台

val isEmpty: Boolean会无法正常编译的isEmpty尚未初始化,对不对?刚开始学习Kotlin。另外,这是get() = field怎么回事?
Shubham A.

1
@Chiaraval的有没有setter
chroder

@chroder是的,您是对的,我必须读错了……评论已删除。感谢您指出
-Chiara

30

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

  • 吸气剂知名度varval属性应该是完全一样的财产的知名度,所以你只能明确地复制性能改进剂,但它是多余的:

    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.
    

在科特林,属性总是通过getter和setter访问,从而有在作出财产无需privatepublic存取像Java中-它支持字段(如果存在的话)已经是私有的。因此,属性访问器上的可见性修饰符仅用于使设置者的可见性不太宽松:

  • 对于具有后备字段和默认访问者的属性:

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

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

可以设置一个并获得不同的类型吗?设置x 等于某值,"Some String"然后返回11字符串的长度,?
卡雷尔

@Carel,不,到目前为止,尚不支持该用例:属性的访问器应与属性的类型完全相同。使用不同的类型可以使用单独的后备属性来解决
热键

天哪,Kotlin非常接近Python,以至于当您被提醒输入它并割断自己的喉咙时,它就可以工作。
卡雷尔

感谢访问修饰符。我private从一个变量中删除了该变量,并使用getter从另一个类中对其进行了访问。
CoolMind

当使用“ var x // private set”组合时,出现“不允许开放式属性使用专用设置方法”。通过声明为“ final var x”解决
汤姆(Tom)

14

1)实施例的默认settergetter用于属性 firstName在科特林

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)示例自定义设置器和获取器。

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,因此感到困惑fieldproperty因为在Java中没有property
某些搜索后,我看到了fieldproperty在科特林样子C#(字段和属性之间的区别是什么?

下面是一些相关的帖子里面谈到fieldpropertyJava和科特林。
java是否具有类似于C#属性的东西?
https://blog.kotlin-academy.com/kotlin-programmer-dictionary-field-vs-property-30ab7ef70531

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


谢谢,对我有帮助!
marcode_ely

8

默认情况下,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}")
}

5

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

Android开发人员的另一本Kotlin教程

物产

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

class Contact(var number: String) {

   var firstName: String? = null
   var lastName: String? = null
   private val hasPrefix : Boolean
       get() = number.startsWith("+")

}

没有太多的代码,但是幕后发生了很多事情。我们将逐步进行。首先,我们创建了一个公开的最终班Contact。

这是我们必须面对的主要规则:如果没有另外指定,则默认情况下,类是公共的和最终的(顺便说一句,类方法也是如此)。如果要从类继承,请使用open关键字标记它。


0

这是一个实用的,真实的Kotlin吸气塞和吸气塞的示例(在此处查看更多详细信息):

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.