当前位置: 代码迷 >> 综合 >> Kotlin中的数据类(data class)和密封类(sealed class)和枚举类(enum class)
  详细解决方案

Kotlin中的数据类(data class)和密封类(sealed class)和枚举类(enum class)

热度:72   发布时间:2023-12-02 17:56:18.0

数据类

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
黄

 

  相关解决方案