Kotlin的吸气剂和二传手

时间:2016-06-19 11:14:04

标签: kotlin getter-setter

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

然而,Kotlin有getters and setters by default。 但我无法理解如何使用它们。

我想说,我想 - 类似于Java:

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

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

7 个答案:

答案 0 :(得分:89)

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访问器附近的私有修饰符,您只能在对象内的方法中设置此值。

答案 1 :(得分:24)

有关属性访问者visibility modifiers的规则如下:

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

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

    protected var x: Int
        get() = 0
        private set(x: Int) { } // Only `private` and `protected` are allowed.
    

在Kotlin中,始终通过getter和setter访问属性,因此不需要像Java一样使用private访问器创建属性public - its backing field (if present)已经是私有的。因此,属性访问器上的可见性修饰符仅用于使setter可见性不那么宽松:

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

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

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

答案 2 :(得分:6)

kotlin中的Getter默认为public,但您可以将setter设置为private,并通过在类中使用一个方法来设置值。像这样。

div {
  border: 1px red solid;
}

.lan_primary {
    width: 100%;
    height: 80vh;
    margin-top: 10vh;
    overflow: hidden;
    .row {
        flex-flow: row !important;
        overflow: hidden;
    }

    &--select,
    &--img {
        padding: 100px 0;
        overflow: hidden;
        position: relative;
    }
    &--select {
        background-color: aqua;
    position: relative;
    overflow:visible;
    &::after{
      content:"";
      position: absolute;
      z-index:1;
      top:0;
      bottom:0;
      height:100%;
      width:20%;
      background-color: cyan;
      right:-40px;
      transform:skew(-20deg);
    }
    }
    &--img {
        background-color: blue;
        transform-origin: top left;
        //margin-left: 80px;
    }
}

答案 3 :(得分:4)

您可以查看本教程了解更多信息:

Yet Another Kotlin Tutorial for Android Developers

  

属性

     

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

class Contact(var number: String) {

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

}
     

代码不多,但背后发生了很多事情   场景。 我们将逐步完成它。首先,我们创建了一个   公共决赛班联系。

     

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

答案 4 :(得分:4)

1)Kotlin中属性 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)

如果您的settergetter与上面的完全相同,则可以将其删除,因为它不必要

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
搜索后,我看到Kotlin中的fieldproperty看起来像C#(What is the difference between a field and a property?

以下是一些相关的帖子,它们讨论了Java和Kotlin中的fieldproperty
does java have something similar to C# properties?
https://blog.kotlin-academy.com/kotlin-programmer-dictionary-field-vs-property-30ab7ef70531

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

答案 5 :(得分:0)

以下是Kotlin吸气和吸气器的实际示例(请参见here的更多详细信息):

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

答案 6 :(得分:0)

如果你有一个 Var 那么你可以:

var property: String = "defVal"
              get() = field
              set(value) { field = value }

但是在Val的情况下,一旦赋值就不能设置,所以不会有setter块:

val property: String = "defVal"
              get() = field

或者如果您不想使用 setter,则:

val property: String = "defVal"
              private set