Kotlin 学习笔记(七)—— Kotlin类与对象之属性与字段


Kotlin学习笔记系列教程

Kotlin 学习笔记(一)—— 概述、学习曲线、开发工具、参考资料
Kotlin 学习笔记(二)—— 基础语法
Kotlin 学习笔记(三)—— 习惯用法
Kotlin 学习笔记(四)—— Kotlin基础之基本类型
Kotlin 学习笔记(五)—— Kotlin基础之控制流、返回与跳转、 包与导入
Kotlin 学习笔记(六)—— Kotlin类与对象之类和继承


属性与字段

声明属性

Kotlin的类可以有属性,属性可以用关键词 var 声明为可变, 否则使用只读关键字 val。

    class Kotlin3 {var name: String = "name"var age: Int = 5var city: String = "Beijing"}
复制代码

要使用一个属性,只需要用名称引用即可,就像Java中的字段:

    fun copyKotlin3(kotlin3: Kotlin3):Kotlin3{val kotlin3 = Kotlin3()kotlin3.age = 30kotlin3.name = "kotlin4"return kotlin3}
复制代码

Getters 与 Setters

声明一个属性的完整语法是

    var <propertyName>[: <PropertyType>] [= <property_initializer>][<getter>][<setter>]
复制代码

其初始化器(initializer)、getter 和 setter 都是可选的。属性类型如果可以从初始化器(或者从其getter 返回值,如下文所示)中推断出来,也可以省略。 例如:

    var defaultSize: Int?  // 错误:需要显式初始化器,隐含默认 getter 和 settervar defaultTime = 1 // 类型 Int、默认 getter 和 setter
复制代码

一个只读属性的语法和一个可变的属性的语法有两方面的不同:1、只读属性的用 val 开始代替 var ,2、只读属性不允许 setter

    val defaultSize: Int?  // 错误:默认 getterval defaultTime = 1 // 类型 Int、默认 getter
复制代码

我们可以自定义访问器,非常像普通函数,刚好在属性声明内部。这里有一个自定义getter 的例子:

    var defaultName: String get() = this.toString()set(value) {value.toUpperCase()}
复制代码

按照惯例,setter 参数的名称是 value,如果你喜欢你可以选择其他名称。 自Kotlin 1.1 起,如果可以从getter 推断出属性类型,则可以省略属性类型:

    var defaultAgeget() = this.toString()  //省略String类型set(value) {value.toUpperCase()}
复制代码

如果你需要改变一个访问器的可见性或者对其注解,但是不需要改变默认的实现,你可以定义访问器而不定义其实现:

    var changeAge: String = "aaa"private set  //此 setter 是私有的并且有默认实现var changeName: String? = null@Inject set // 用 Inject 注解此 setter
复制代码

幕后字段

在kotlin 类中不能直接声明字段。然而,当一个属性需要一个幕后字段时,Kotlin 会自动提供,这个幕后字段可以使用field 标识符在访问器中引用:

    var count = 1set(value) {if (value > 0) field = value}
复制代码

field 标识符只能用在属性的访问器内

如果属性至少一个访问器使用默认实现,或者自定义访问器通过 field 引用幕后字段,将会为该属性生成一个幕后字段

例如,下面情况,就没有幕后字段:

    val height: Intget() = defaultTime
复制代码

幕后属性

如果你的需求不符合这套"隐式的幕后字段"方案,那么总可以使用幕后属性(backing property):

    private var _table: Map<String, Int>? = nullpublic val table: Map<String, Int>get() {if (_table == null) {_table = HashMap() // 类型参数已推断出}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() { …… }复制代码

延迟初始化属性与变量

一般地,属性声明为非空类型必须在构造函数中初始化。然而,这经常不方便。例如:属性可以通过依赖注入来初始化,或者在单元测试的setup方法中初始化,这种情况下,你不能在构造函数内提供一个非空初始器,但你仍想在类体中引用该属性时避免空检查。 为处理这种情况,你可以用 lateinit 修饰符标记该属性:

public class MyTest {lateinit var subject: TestSubject@SetUp fun setup() {subject = TestSubject()}@Test fun test() {subject.method()  // 直接解引用}
}
复制代码

该修饰符只能用于类体中的属性(如果在主构造函数中声明的 var 属性,并且仅当该属性没有自定义 getter 或 setter 时),而自 Kotlin 1.2 起,也用于顶层属性与局部变量。该属性或变量必须为非空类型,并且不能是原生类型。

在初始化前访问一个 lateinit 属性会抛出一个特定异常,该异常明确标识该属性被访问及它没有初始化的事实。

检测一个 lateinit var 是否已初始化(自 1.2 起)

要检测一个 lateinit var 是否经过初始化,请在该属性的引用上使用 .isInitialized:

if (foo::bar.isInitialized) {println(foo.bar)
}
复制代码

此检测仅对可词法级访问的属性可用,即声明位于同一个类型内、位于其中一个外围类型中或者位于相同文件的顶层的属性。

覆盖属性

参见第 Kotlin 学习笔记(六)—— Kotlin类与对象之类和继承 ---- 覆盖属性

委托属性

最常见的一类属性就是简单地从幕后字段中读取(以及可能的写入)。另一方面,使用自定义getter 和 setter 可以实现属性的任何行为,介于两者之间,属性如何工作有一些常见的模式,一些例子:惰性值、通过键值从映射读取。访问数据库。访问时通知侦听器等等。

这些常见行为可以通过委托属性实现为库,会在后续文章中介绍


本篇主要介绍了Kotlin类与对象之属性与字段,下篇文章学习kotlin之接口


个人博客地址:http://outofmemory.top/
CSDN地址:http://blog.csdn.net/dazhaoDai
GitHub地址:https://github.com/dazhaoDai


Kotlin 学习笔记(七)—— Kotlin类与对象之属性与字段相关推荐

  1. Kotlin学习笔记 第二章 类与对象 第十四 十五节 委托 委托属性

    参考链接 Kotlin官方文档 https://kotlinlang.org/docs/home.html 中文网站 https://www.kotlincn.net/docs/reference/p ...

  2. Kotlin学习笔记 第二章 类与对象 第一节类与继承(补)

    参考链接 Kotlin官方文档 Kotlin docs | Kotlin 本系列为参考Kotlin中文文档 kotlin官方文档2020版.pdf-其它文档类资源-CSDN下载 第二章 第一节 类与继 ...

  3. Kotlin学习笔记 第二章 类与对象 第十二 十三节 对象表达式与对象声明 类型别名

    参考链接 Kotlin官方文档 https://kotlinlang.org/docs/home.html 中文网站 https://www.kotlincn.net/docs/reference/p ...

  4. Kotlin学习笔记 第二章 类与对象 第五节 可见性 第六节 扩展

    参考链接 Kotlin官方文档 https://kotlinlang.org/docs/home.html 中文网站 https://www.kotlincn.net/docs/reference/p ...

  5. Kotlin学习笔记 第二章 类与对象 第三节接口 第四节 函数式接口

    参考链接 Kotlin官方文档 https://kotlinlang.org/docs/home.html 中文网站 https://www.kotlincn.net/docs/reference/p ...

  6. Kotlin学习笔记 第二章 类与对象 第七节 数据类

    参考链接 Kotlin官方文档 https://kotlinlang.org/docs/home.html 中文网站 https://www.kotlincn.net/docs/reference/p ...

  7. Kotlin学习笔记 第二章 类与对象 第十一节 枚举类 第八节密封类

    参考链接 Kotlin官方文档 https://kotlinlang.org/docs/home.html 中文网站 https://www.kotlincn.net/docs/reference/p ...

  8. Kotlin学习笔记 第二章 类与对象 第二节属性

    参考链接 Kotlin官方文档 https://kotlinlang.org/docs/home.html 中文网站 https://www.kotlincn.net/docs/reference/p ...

  9. Kotlin学习笔记 第二章 类与对象 第九节 泛型

    参考链接 Kotlin官方文档 https://kotlinlang.org/docs/home.html 中文网站 https://www.kotlincn.net/docs/reference/p ...

  10. Kotlin学习笔记 第二章 类与对象 第十节 内部类嵌套类

    参考链接 Kotlin官方文档 https://kotlinlang.org/docs/home.html 中文网站 https://www.kotlincn.net/docs/reference/p ...

最新文章

  1. linux 切换python版本_Linux下python默认版本切换成替代版本(示例代码)
  2. 给你两个经纬度,计算他们之间的距离
  3. 高效缓存Memcached 集成使用说明
  4. 刷机android8.1 错误7,[Android]错误: -source 1.7 中不支持 lambda 表达式 (请使用 -source 8 或更高版本以启用 lambda 表达式)...
  5. Codeforces Round #733 (Div. 1 + Div. 2) E. Minimax 分情况讨论 + 思维
  6. 毕业与计算机专业,电子与计算机工程专业毕业后干什么
  7. Drupal 7 主题模板概述
  8. 社区团购还是两看,从消极这个角度
  9. exec还原oracle,symantec Backup exec 恢复Recovery Oracle 数据库
  10. tp5时间戳转换日期格式
  11. Beyond Compare不能打开*.te文件解决方案
  12. 转:一个基于互联网医疗的创业公司,三年是一个收获
  13. python一行输入两个数据中间用空格隔开
  14. BaiduMap---百度地图官方Demo之离线地图功能(介绍如何下载和使用离线地图)
  15. PTA-整除光棍(C语言)
  16. zemax模拟ld_使用ZEMAX 序列模式模拟激光二极管光源
  17. R语言使用符号函数计算数据的正负特性、sign函数计算数据的正负符号返回0、1、-1
  18. 阿龙的学习笔记--- B-树和B+树 以及 MySQL的索引机制总结
  19. Python如何获取 Jenkins构建日志
  20. Delphi DeviceIoControl函数

热门文章

  1. 校外访问不了cgbt.cn(403 forbidden)解决办法
  2. err-disabled
  3. 雷林鹏分享:YII 模型-视图-控制器(MVC)设计模式
  4. ROS系统MoveIt玩转双臂机器人系列(二)--生成MoveIt配置包
  5. Struts2+Spring+Hibernate step by step 11 ssh拦截验证用户登录到集成
  6. 了解DJango模板系统
  7. 高效代码之strcpy()实现
  8. AjaxPro无刷新选择列表框/下拉框[方便|稳定]
  9. Saying Good-bye to Cambridge Again --by Xu Zhimo
  10. ceph基本架构及数据分布原理