美文网首页
【KtAndroid - 9】数据类与密封类

【KtAndroid - 9】数据类与密封类

作者: 会飞的小魚 | 来源:发表于2020-05-10 14:19 被阅读0次

这次更新文章间隔有点久……没办法,农村娃儿,在加上每天的网课……不过,幸好是要开学了。

喜大普奔。

也刚好乘着今天这个特殊的日子:

祝自己的妈妈,以及天下所有的妈妈!母亲节快乐!

1.jpg

emmm……

前面我们说了类与对象,类是对象的模板,对象是类的实现

然,kotlin完美吸收了java的面向对象思想,并且!还添加了一系列诸如数据类密封类等新的特性。

数据类

java编程中,我们通常会封装一个JavaBean来实现各种数据,在kotlin中则是将这种封装单独了出来,专门用一种以data关键字作为定义而生成的类,我们首先来看看数据类的定义。

data class UserBean(val name:String, val pass:String){……}

按照官网文档所说:

  • 主构造函数需要至少有一个参数;
  • 主构造函数的所有参数需要标记为 valvar
  • 数据类不能是抽象、开放、密封或者内部的;
  • (在1.1之前)数据类只能实现接口。

意思很明确了吧,

此外,数据类不能被继承!

2.png

但是数据类又继承自Any(也就是java中的Object)

所以,它存在以下方法:

  • equals() / hashCode()
  • toString()
  • componentN()
  • copy()

接下来,我们来看看这些方法!

3.png 4.png 5.png

以上是继承自Any的基本方法,另外我们再来看两个加粗的方法。

先说copy(),复制。

6.png 7.png

上图很清晰明了,copy() 的产生理由:某些时候需要改变对象的<font color=red>部分属性</font>但又要保持其自身的其他属性不变。

源代码很简单:

@NotNull
   public final UserBean copy(@NotNull String name, @NotNull String pass) {
      Intrinsics.checkParameterIsNotNull(name, "name");
      Intrinsics.checkParameterIsNotNull(pass, "pass");
      return new UserBean(name, pass);
   }

然后就是这里的Intrinsics.checkParameterIsNotNull方法。

public static void checkParameterIsNotNull(Object value, String paramName) {
        if (value == null) {
            throwParameterIsNullException(paramName);
        }
    }

很简单吧,就是一个判空函数。

解构函数

然后,就是另一个加粗的componentN()了,注意了,这里的N并不是字母,而是number数字。

首先来举个栗子。

8.jpg

看到了吧,就是这样!

嘿嘿,开玩笑。

fun main(args: Array<String>) {
    val user: UserBean = UserBean("张三", "123")
    val user1: UserBean = UserBean("李四", "12346578")
    ……
    //componentN()
    val (cName, cAge) = user
    println(cName)
    println(cAge)
}
9.png

怎么样?看懂没?

不懂没关系,我也不懂。

10.png 11.png

这样看明白了吧?

还不明白?

那我们来看看源码

12.png

kotlin为每一个数据类成员都声明了一个componetN,以供解构函数的调用

也就是说

val (name, age) = user
//等同于
val name = user.component1()
val age = user.component2()

在之前循环一节我也提到过

for( (key,vlaue) : map ){
  println("key=$key,value=$vlaue")
}

上例也是使用的解构函数,值得注意的是:一旦使用了解构函数!解构列表需要与主构造器中的参数列表的,数量、类型,一一对应。

密封类

密封类?蜜蜂类?好吧……皮一下,不要在意这些无关紧要的细节。

kotlin中的密封类与枚举有些类似,它是定义了受限制的类继承结构。

字面意思来理解就是……

类中的类型只能是有限的几种类型,不能是其他的类型

按照枚举的说法就是,只能是枚举类的东西,其他东西枚举类匹配不到

避免混淆,我先说明一下:

  • 密封类是允许被继承的,但是!密封类的继承只能在同一个文件之中进行(kt1.1版本之前还只能允许嵌套在其内部……)
  • 密封类不能被直接实例化,它是一个隐藏的抽象类的
  • 密封类只允许有private的构造函数!

密封类的定义关键字:sealed

来看代码

//定义密封类(空类)
sealed class SealedExpr

//继承
data class Car(val name: String, val type: String) : SealedExpr()
data class Food(val fName: String, val fType: String) : SealedExpr()


//run
fun main() {
    val car: SealedExpr = Car("大众", "白色");
    val food: SealedExpr = Car("西红柿", "红色");

    println(test(car))
    println(test(food))
}
fun test(p: SealedExpr): String = when (p) {
    is Car -> p.cName
    is Food -> p.fName
}

在内部定义

sealed class SealedExpr1{
    data class Car1(val cName: String, val cType: String) : SealedExpr1()

    data class Food1(val fName: String, val fType: String) : SealedExpr1()
}

//run
fun main() {
    val car: SealedExpr1 = SealedExpr1.Car1("大众", "白色");
    val food: SealedExpr1 = SealedExpr1.Car1("西红柿", "红色");

    println(test(car))
    println(test(food))
}

fun test(p: SealedExpr1): String = when (p) {
    is SealedExpr1.Car1 -> p.cName
    is SealedExpr1.Food1 -> p.fName
}

这就完了,但是为什么上面要说它与枚举类类似呢?

这就来说说:

  • 就那when表达式来说,一旦when表达式中使用了超类,如上例中的:SealedExpr那么只要是继承自SealedExpr的子类必须要全部写,否则你只能写else,枚举也是一样的。
13.png
  • 但是密封类与枚举类又不一样,枚举类只能存在一个实例,然而密封类可以存在多个实例。
14.png

总结

  • 本来想把泛型也一起写了,但是……再写下来好像有点多了,下回分解吧。
  • kotlin中存在数据类(data)与密封类(saled)。
  • 数据类无法被继承,不能拥有子类,必须拥有至少带一个参数的构造方法,kotlin为每一个密封类成员都提供了一个componetN以便于解构函数调用。
  • 密封类允许被继承,但是!只能在同一个文件或者该密封内内部继承,且密封类的构造函数只能是private
15.png

相关文章

  • 【KtAndroid - 9】数据类与密封类

    这次更新文章间隔有点久……没办法,农村娃儿,在加上每天的网课……不过,幸好是要开学了。 喜大普奔。 也刚好乘着今天...

  • Kotlin学习笔记之 9

    9.Kotlin 数据类与密封类 数据类在class前面加上data关键字,这个类就变成了数据类,会自动添加我们一...

  • 数据类与密封类

    package shujuleiyumifenglei/*Kotlin 可以创建一个只包含数据的类,关键字为dat...

  • Kotlin 数据类与密封类

    数据类 我们经常创建一些只保存数据的类。在这些类中,一些标准函数往往是从数据机械推导而来的。Kotlin 中使用关...

  • Kotlin 数据类与密封类

    数据类 Kotlin 可以创建一个只包含数据的类,关键字为 data: 编译器会自动的从主构造函数中根据所有声明的...

  • Kotlin 数据类与密封类

    数据类 Kotlin 可以创建一个只包含数据的类,关键字为 data:data class User(val na...

  • android巩固-kotlin第二篇

    类和对象 继承 接口 扩展 数据类和密封类

  • Android MVI 设计模式(3)

    我们用 kotlin 的 sealed 类密封一些数据类,kotlin 提供的密封类类似于枚举,密封类用于定义一种...

  • 【runoob.11】数据类与密封类

    数据类以及解构声明 组件函数允许数据类在解构声明中使用: 密封类 密封类用来表示受限的类继承结构:当一个值为有限集...

  • 【KtAndroid - 6】类与对象

    类与对象之间的关系 直接进入主题。 类:对象的模板 对象:类的实现 类只有通过(new Instance)对象实例...

网友评论

      本文标题:【KtAndroid - 9】数据类与密封类

      本文链接:https://www.haomeiwen.com/subject/wfrjnhtx.html