数据类
1.什么是data class
data class 就是一个类中包含一些数据字段。
2.Kotlin中 data class 设计的好处
在Java中我们常用的bean类,每一个变量我们都需要写getter,setter方法,有时候还要重写toString,equals等方法,尽管工具会帮我们一键生成,但是代码量要写很多,显得有点臃肿,不灵活。
例如:同样实现一个bean类,Java的实现方式是
public class JavaBean {private String name;private int age;public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic String toString() {return "JavaBean{" +"name='" + name + '\'' +", age=" + age +'}';}
}
而在Kotlin中:一行代码搞定~~
data class KotlinBean(val name:String,val age:Int)
这是由于在Kotlin中我们不需要手动去敲这些代码了,编译器在背后默默给我们生成了这些东西
- setter/getter
- toString()
- equals()
- hashCode()
- componentN()
- copy()
前三个方法是Kotlin中超级父类Any类中定义的。
copy()方法:就是创建一个当前对象的一份拷贝,并且在copy的过程中可以选择性改变拷贝对象的属性值,而原来对象的属性值不会改变。浅拷贝
componentN()方法:能够保证数据类可以使用解构声明,有了这个解构申明,想在一个函数中返回多个结果,就可以申明一个简单的数据类来返回了,然后取值也很方便。
data class KotlinBean(val name: String, val age: Int)fun main(args: Array<String>) {var bean: KotlinBean = KotlinBean("zhangSan", 20)var (name, age) = bean //多重赋值println("$name,$age")//给name赋值其实是调用的bean.component1(),给age赋值调用的是component2()函数
}zhangSan,20
3.Kotlin中定义data class类需要注意的地方有哪些?
Kotlin中可以创建一个只包含数据的类,称之为数据类,使用关键字data定义
数据类需要满足以下条件
- 主构造函数至少包含一个参数
- 所有的主构造函数的参数必须标识为val或var
- 数据类不可以声明为abstract、open、sealed和inner的
- 数据类不能继承其他类,但可以实现接口
- 使用data修饰的数据类,Kotlin会默认帮我们生成getter/setter,copy,toString(),hashCode,equals等方法
data修饰的类并没有无参构造方法,并且该类名是final修饰的 Kotlin中提供了两个插件来解决这两个问题,allOpen是为了去除final修饰,noArg是为了添加无参构造方法。
密封类
1.什么是密封类?
密封类用来表示受限的类继承结构:当一个值为有限几种的类型, 而不能有任何其他类型时。在某种意义上,他们是枚举类的扩展.
2.如何声明一个密封类?
声明一个密封类,使用 sealed 修饰类,密封类可以有子类,但是所有的子类都必须要内嵌在密封类中。
sealed class Animalfun main(args: Array<String>) {say(Dog())say(Cat())
}fun say(animal: Animal) {//密封类的好处就在于:使用when表达式时,如果能覆盖所有情况是不需要添加else子句的when (animal) {is Dog -> animal.yell()is Cat -> animal.wow()}
}class Dog : Animal() {fun yell() {println("wangwangwang")}
}class Cat : Animal() {fun wow() {println("miaomiaomiao")}
}wangwangwang
miaomiaomiao
3.密封类与枚举类的区别?
枚举类的每个枚举常量只存在一个实例,
密封类的一个子类可以有可包含状态的多个实例!
4.密封类的特点
密封类的所有子类都必须与密封类在同一文件中
密封类子类的子类(间接继承者)可以放在任何位置,无需在同一个文件中
枚举类
java中的枚举类使用enum代替class声明,每一个枚举值代表一个类的实例。
在Kotlin中,枚举类的声明是在class前边加上enum关键字
fun main(args: Array<String>) {printAllValues<Color>() //输出RED,GREEN,BLUEprintln(getChinese(Color.YELLOW))
}/*** 枚举类的使用* 枚举类常量用逗号分隔,每个枚举常量都是一个对象* */
enum class Color {RED, YELLOW, BLUE, BLACK, WHITE
}//自 Kotlin 1.1 起,可以使用 enumValues() 和 enumValueOf() 函数以泛型的方式访问枚举类中的常量
inline fun <reified T : Enum<T>> printAllValues() {println(enumValues<T>().joinToString { it.name })
}fun getChinese(color: Color) =when (color) { //when是一个有返回值的表达式Color.BLACK -> "红"Color.BLUE -> "蓝"Color.RED -> "红"Color.WHITE -> "白"Color.YELLOW -> "黄"}RED, YELLOW, BLUE, BLACK, WHITE
黄