IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> 【深入kotlin】-数据类和密封类 -> 正文阅读

[移动开发]【深入kotlin】-数据类和密封类

Data class

定义

Kotlin 中对 java 中的 pojo 类型进行了专门的支持和简化,叫做数据类(data class)。一个数据类的定义非常简单,仅有一个主构造方法即可:

data class Person(val name: String, var age:Int, var address:String)

// 使用 data class
var person = Person("zhangshan",30,"shanghai")
println(person)// 输出 Person(name=zhangshan, age=30, address=shanghai)

数据类的定义有如下特点:

  • 主构造方法至少有一个参数。

  • 所有的主构造参数必须声明为属性,即必须声明可变性,要么 val,要么 var。

  • 数据类不能说 abstract\open\sealed\internal

自动创建的方法

从中不难猜出,data class 和 lombok 一样,自动为 Person 类创建了一系列的方法,比如:

  • getter/setter
  • toString 方法
  • equals 和 hashCode 方法。
  • component1…N 方法,按照属性声明顺序定义。
  • copy 方法,用于对象复制。

继承和覆盖

数据类的成员可以被重写,但有一些限制:

  • 如果数据类中显式定义了 equals\hashCode\toString 方法,或者数据类的父类中将这些方法指定为 final,那么编译器不会创建这些方法,转而使用显式定义的方法。
  • 如果父类中定义了 componentN 方法,并且方法是 open 且和编译器生成的方法类型兼容,那么编译器生成的方法会被重写父类方法;如果父类中这些方法类型不兼容或者被定义为 final,则编译器会报错。
  • 不允许重写数据类的 componentN/copy 方法(允许重载,但不允许重写)。

copy 方法

数据类的 copy 方法用于对象复制,特别是对于大部分属性相同,但有部分属性不同的对象:

var person = Person("zhangshan",30,"shanghai")
var person2 = person.copy(address="hangzhou") // 必须指定参数名
println(person2) // 打印:Person(name=zhangshan, age=30, address=hangzhou)

这样只是覆盖了 person 对象的 address 值,其它属性原样复制。调用 copy 方法时,最好指定参数名,如果不指定,默认会按照参数顺序传参,这个结果可能不可预期的。

访问属性

数据类的属性访问都是可以直接访问的:

	person.age = 20
	println(person.age)

注意,虽然编译器为每个属性生成了 geter/setter 方法,但那是字节码,在 kotlin 中这些方法是不可访问的。

componentN 方法和解构声明

数据类的主方法中声明的每个参数,都会有一个对应的componentN 方法,N 被参数的顺序替换,从 1 开始。

componentN 方法返回的其实就是每个属性的对应字段,这些方法实现了 kotilin 的解构声明。

什么叫解构声明?其实就是 decode,我们可以使用如下语法将一个数据类的属性读取到一个元组(同 Swift Tuple):

var (name, age, address)=person
println("{$name,$address,$age}")

解构时,person 的属性依照声明的先后顺序读取到左边的变量中。

在 kotlin 中,解构声明通常会和数据类一起使用:

data class Person(val name: String, val age: Int)
... ...
val (name,age) = Person("zhangsan",30)
println(name)
println(age)

解构声明可以通过类型推断获知 component 的类型,但也可以显示指定 component 的类型,可以全部指定,也可部分指定。

val (_, age:Int) = Person("zhangsan", 30)

Pair 和 Triple

Pair 和 Triple 用于让函数突破只能返回单个值的限制。Pair 返回 2 个值,Triple 返回 3 个值。

fun test(): Pair<String,Int>{
	return Pair("Zhansan",40) // 1
}
... ...
val (name, age) = test() // 2
  1. test 函数返回一个 Pair,在 Pair 中包含了两个值。
  2. 利用解构声明,读取返回值中的两个值。在 Pair 中,这两个值也可以用 first 和 second 来访问。

Map 的解构

val map = mapOf("a" to "aa","b" to "bb", "c" to "cc")
for((key, value) in map){ // 1
	println("key:$key, value:$value")
}
map.mapValues { // 2
  (_, value) -> "$value hello" // 3
}
  1. 利用解构声明遍历 key 和 value。
  2. mapValues 方法可以将 map 中的所有 value 转换成另外一个值和类型,key 不变。mapKeys 则转换 key 的值和类型。
  3. 这里我们将每个 value 后面加上了一个 hello。类型仍然是 String。

无参构造器

数据类要求主构造方法至少有一个参数,如果需要使用无参构造方法,只能为每个参数提供默认值来实现:

data class Person(val name: String="", var age:Int=0, var address:String="")

在字节码层级,就会生成一个无参的构造方法。

密封类

Kotlin 用密封类来描述子类受限制的类。

  • 密封类的子类必须和密封类位于同一文件(kotlin 1.1 以后)。
  • 密封类的子类如果不是密封的,那么它的子类可以定义在任何地方。
  • 密封类是抽象的,不能实例化。
  • 不允许非私有的构造方法。

密封类的一种常见应用场景是在 when 语句中使用,使得不必提供 else:

sealed class Calculator()
class Add:Calculator
class Subtract:Calculator
fun calculate(a: Int, b: Int, cal: Calculator) = when(cal) {
	is Add -> a+b
	is Subtract -> a-b
}
fun main(args: Array<String>){
	println(caculate(1,2, Add()))
	println(caculate(3,2, Substract()))
}

when 语句中对密封类的所有子类进行枚举,如果 cal 对象属于该密封类的特定子类时,执行特定的操作。由于密封类的子类已经在 when 表达式内部列举尽了,所以无需 else 子句。

所以密封类更像是一种枚举类型,用于表示父类和子类之间的关系是可列举的,而枚举类型用于表示类型和实例之间的关系是可列举的。

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-12-10 11:10:25  更:2021-12-10 11:12:06 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 7:43:37-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码