例如,在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.
那么吸气剂是如何工作的?
答案 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的规则如下:
var
和val
属性的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
的示例默认getter
和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,所以我对field
和property
感到困惑,因为在Java中没有property
。
搜索后,我看到Kotlin中的field
和property
看起来像C#(What is the difference between a field and a property?)
以下是一些相关的帖子,它们讨论了Java和Kotlin中的field
和property
。
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