Kotlin Reference (九) Properties and Fields
most from reference
声明属性
Koltin的类都有属性,这些属性可以声明为可变的,使用var关键字或用val关键字生声明不可变属性。
class Address {
var name: String = ...
var street: String = ...
var city: String = ...
var state: String? = ...
var zip: String = ...
}
要使用一个属性,我们简单地通过名称引用他,就好像Java中的一个字段:
fun copyAddress(address: Address): Address {
val result = Address() // there's no 'new' keyword in Kotlin
result.name = address.name // accessors are called
result.street = address.street
// ...
return result
}
Getters and Setters
声明属性的完整语法是:
var <propertyName>[: <PropertyType>] [= <property_initializer>]
[<getter>]
[<setter>]
初始化程序,getter和setter是可选的,如果可以从初始化程序(或从getter返回类型,如下所示)推断属性类型,则属性类型时可选的。
例子:
var allByDefault: Int? // error: explicit initializer required, default getter and setter implied
var initialized = 1 // has type Int, default getter and setter
只读属性声明的完整语法与可变的属性声明的不同之处有两点:①关键字是val ② 不允许set重新赋值
val simple: Int? // has type Int, default getter, must be initialized in constructor
val inferredType = 1 // has type Int and a default getter
我们可以在一个属性声明中写出自定义setter,非常像普通功能。一下是一个定制getter的例子:
val isEmpty: Boolean
get() = this.size == 0
自定义setter如下所示:
var stringRepresentation: String
get() = this.toString()
set(value) {
setDataFromString(value) // parses the string and assigns values to other properties
}
按惯例,setter参数的名称是value,也可以选择其他名称。
从Kotlin1.1起,如果可以从getter推断属性类型,则可以省略它:
val isEmpty get() = this.size == 0 // has type Boolean
如果您需要更改访问器或者注释它,但不需要更改默认实现,则可以定义访问器而不定义其主体:
var setterVisibility: String = "abc"
private set // the setter is private and has the default implementation
var setterWithAnnotation: Any? = null
@Inject set // annotate the setter with Inject
后备字段
Kotlin中的类不用有字段,但是,有时在使用自定义访问器时需要一个后备字段。所以,kotlin提供了一个可以使用field关键字标识符访问的自动备份字段:
var counter = 0 // the initializer value is written directly to the backing field
set(value) {
if (value >= 0) field = value
}
```
field标识符只能在属性的访问中使用。
如果属性使用至少一个访问器的默认实现,或者自定义访问器通过field标识符引用它,则将为属性生成后备字段。
例如,在以下情况下,将不会有后备字段:
```
val isEmpty: Boolean
get() = this.size == 0
后备属性
如果你想做一些不符合这个“隐性支持字段”方案的东西,你总是可以回到拥有一个后备属性:
private var _table: Map<String, Int>? = null
public val table: Map<String, Int>
get() {
if (_table == null) {
_table = HashMap() // Type parameters are inferred
}
return _table ?: throw AssertionError("Set to null by another thread")
}
与Java中一样,因为使用默认getter和setter的私有属性的访问优化,因为不会引入函数调用开销。
编译时常数
在编译时已知其值的属性可以使用修饰符标记为编译时常数const。这些属性需要满足以下要求:
- 顶级或成员 object
- 用类型String或原始类型的值初始化
- 没有自定义的getter方法
这些属性可以在注释中使用:
const val SUBSYSTEM_DEPRECATED: String = "This subsystem is deprecated"
@Deprecated(SUBSYSTEM_DEPRECATED) fun foo() { ... }
后期初始化属性
通常,声明为非空类型的属性必须在构造函数中进行初始化。然而,这通常不方便。例如,可以通过依赖注入或单元测试的设置方法初始化属性。在这种情况下,您不能在构造函数中提供非空的初始值设置,但是您仍然希望在引用类的正文中的属性时避免空检查。
要处理这种情况,您可以使用lateinit修饰符标记属性:
public class MyTest {
lateinit var subject: TestSubject
@SetUp fun setup() {
subject = TestSubject()
}
@Test fun test() {
subject.method() // dereference directly
}
}
修饰符只能用于在var一个类的主体内声明的属性(不在主构造函数中),只有在该属性没有自定义的getter或setter 时才可以使用。属性的类型必须为非空值,并且不能为原始类型。
lateinit在初始化之前访问一个属性会引发一个特殊的异常,它清楚地标识被访问的属性以及它还没被初始化的事实。
覆盖属性
请参考覆盖属性
委托属性
最常见的属性只是读取(也可能写入)支持字段。另一方面,使用定制getter和setter可以实现属性的任何行为。中间的某个地方,财产如何运作有一些共同的模式。几个例子:懒惰值,通过给定的键读取地图,访问数据库,通知访问者等。
这样的常见行为可以使用委托属性作为库来实现。
Kotlin Reference (九) Properties and Fields的更多相关文章
- Kotlin Reference (十二) Extensions
most from reference Kotlin与C#和Gosu类似,提供了扩展一个新功能的类,而不必继承类或使用任何类型的设计模式,如Decorator(装饰者模式).这是通过称为扩展的特殊声明 ...
- Kotlin Reference (二) Idioms
most from reference 一些常用操作 创建单例类 object 数据类data classList.Map.Array的简单操作Lazy延迟加载属性空类型?空类型表达式?..?:.?. ...
- Kotlin Reference (十一) Visibility Modifiers
most from reference 类,对象,接口,构造函数,函数,属性及setters具有可见性修饰符(getter总是具有和属性一样的可见性).在kotlin中油4个可视化修饰符:privat ...
- Kotlin Reference (十) Interfaces
most from reference 接口 Kotlin中的接口非常类似于Java8,它们可以包含抽象方法的声明以及方法实现.与抽象类不同的是接口不能存储状态.它们可以具有属性,但这些需要是抽象的或 ...
- Kotlin Reference (八) Classes and Objects
most from reference 类 Kotlin的类的声明使用关键字class class Invoice { } 类声明由类名.类头(指定其类型参数,构造函数等)和类体组成,由大括号括起来. ...
- Kotlin Reference (七) Returns and Jumps
most from reference kotlin有三个结构跳跃表达式 return 默认情况下,从最近的封闭函数或匿名函数返回. break 跳出整个循环 continue 跳出本次循环,进行下一 ...
- Kotlin Reference (六) Control Flow
most from reference if表达式 在kotlin中,if是一个表达式,即它返回一个值.kotlin中没有Java中的三元运算符. // Traditional usage var m ...
- Kotlin Reference (五) Packages
most from reference 包 源文件可以从包声明开始: package foo.bar fun baz() {} class Goo {} // ... 源文件的所有内容(如类和函数)都 ...
- Kotlin Reference (四) Basic Types
most from reference 基本类型 在kotlin中,一切都是对象,我们可以在任何变量上调用成员函数和属性.一些类型可以具有特殊的内部表示:例如,数字.字符和布尔值都可以在运行时被表示为 ...
随机推荐
- POJ1273:Drainage Ditches(最大流入门 EK,dinic算法)
http://poj.org/problem?id=1273 Description Every time it rains on Farmer John's fields, a pond forms ...
- Sparsity稀疏编码(二)
为了更进一步的清晰理解大脑皮层对信号编码的工作机制(策略),需要把他们转成数学语言,因为数学语言作为一种严谨的语言,可以利用它推导出期望和要寻找的程式.本节就使用概率推理(bayes v ...
- MFC中Doc类获取View类的方法(SDI)
从view类中获取Doc的方法如下: CYourDoc* pDoc = GetDocument(); 这个函数已经写好,所以无需自己添加,使用时直接利用pDoc即可. 若反过来,从Doc中获取View ...
- Egret引擎开发基础(一)
显示图片 var batman:egret.Bitmap = new egret.Bitmap( RES.getRes('hexo-huaheshang_png')); batman.x = 0; b ...
- HBase优化相关
1.HBase预分区 HBase在创建表时,默认会自动创建一个Region分区.在导入数据时,所有客户端都向这个Region写数据,直到这个Region足够大才进行切分.这样在大量数据并行写入时,容易 ...
- 【bzoj4972】小Q的方格纸 前缀和
题目让O(1)预处理出来 类三角形边界及内部的和 根据这个图 就是一个大矩形-左边的绿色的矩形 - 蓝色的大三角形 + 右上角突出的蓝色的小三角形 #include<bits/stdc++.h& ...
- python swap
swap里面的a,b 不会影响函数作用域外面的变量 java也不可以的吧:python里面没有指针,你可以认为所有的东西都是指向的内容,但是不要试图去改变指针的值 其实我觉得所有的对象都是不可变对象, ...
- [原][osgearth]osgearthviewer读取earth文件,代码解析(earth文件读取的一帧)
跑osgearthviewer程序 使用一个earth文件做参数传入 跟进代码. 首先osgearthviewer程序加载earth的方式分为两种: 1.根据earth文件(load方式) 2.使用S ...
- 使用git bush 生成github SSH公钥
1 如果没有安装ssh,那么使用下面的指令 sudo apt-get install ssh 2 检查SSH公钥 cd ~/.ssh 看看存不存在.ssh,如果存在的话,掠过下一步:不存在的请看下一步 ...
- 何时使用MQ ?
何时使用MQmq作为一种基础中间件在互联网项目中有着大量的使用. 一种技术的产生自然是为了解决某种需求,通常来说是以下场景: 需要跨进程通信:B系统需要A系统的输出作为输入参数.当A系统的输出能力远远 ...