文章19 | 阅读 9946 | 点赞0
一、数据类(data class)
在介绍数据类之前,我们先来看看这样一段代码:
class Student(val name: String, var age: Int)
fun main(args: Array<String>) {
val student = Student("David", 12)
println(student)
}
此时会打印:
com.xlh.test.data.Student@49476842
大家都知道,这样直接打印student,会导致Student类的toString方法得到调用,最终打印到控制台的结果就是toString方法的返回结果。而Object类中的toString方法的实现(这里你可能产生疑问,Kotlin中的超级父类是Any类型,而不是Object类型,它俩的关系参看这篇博客):
所以就会出现前面的输出结果。
现在我们在类的声明前添加data关键字:
data class Student(val name: String, var age: Int)
其他不变,再看输出:
发生变化了,那就说明添加了data关键字后,Student类toString方法被重写了,并且形式为(属性名=属性值...),逗号分隔。实际上此时Student类就是一个数据类。
在类的声明前添加data关键字,即可将一个类定义成数据类。
c) 数据类不能是abstract、open、sealed和inner的
可以看到,一旦添加了data关键字,类的结构会发生变化,添加了很多方法,这就和扩展不一样了。我们来总结一下一共添加了哪些方法:
前面三个方法都是kotlin.Any类中的定义的,在数据类中会被重写。接下来我们来介绍一下后面两个稍微陌生的方法:
val copyStudent = student.copy(name = "xlh", age = 12)
println(copyStudent)
打印:
这样就会创建一个新的对象并且修改了它的只读属性然后返回。注意:
i. 原来的Student对象的属性值并没有改变
ii. 参数的传递问题:可以不传,表示不修改属性值;如果传递的参数不是按照声明的顺序,那么必须使用有名参数的形式来调用,其他的情况下任意。
总结copy方法的作用:就是创建一个当前对象的一份拷贝,并且在copy的过程中可以选择性改变拷贝对象的属性值,而原来对象的属性值不会改变。注意这里是浅拷贝。
val (name, age) = student
println("$name, $age")
此时就可以输出:
在第3点中列出的方法里,只针对定义在主构造函数中的属性,如果你定义了一个属性:
data class Student(val name: String, var age: Int) {
var address = "beijing"
}
这个address属性就不会被考虑。
二、密封类(sealed class)
sealed class Animal
class Dog : Animal() {
fun bark() {
println("wangwangwang")
}
}
class Cat : Animal() {
fun miao() {
println("miaomiaomiao")
}
}
fun sayHello(animal: Animal) {
when (animal) {
is Dog -> animal.bark() //Smart Cast
is Cat -> animal.miao()
//Don’t need else
}
}
fun main(args: Array<String>){
sayHello(Dog())
sayHello(Cat())
}
密封类从某种程度上可以说子类的枚举化,从类的层次上进行了限制。
密封类子类的子类可以定义在任何地方,并不需要和密封类定义在同一个文件中。
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/xlh1191860939/article/details/79650126
内容来源于网络,如有侵权,请联系作者删除!