- 数据类:java的数据类和普通类一样,通常声明属性及其对应的set和getapi,同时封装和当前数据类相关的逻辑方法,kotlin的数据类和java类不一样,语法上需要使用关键字data声明,其他要点整理如下:
-
针对kotlin的数据类,kotlin会根据主构造函数中的所有属性自动生成下面几个函数:
自动生成函数
备注:
* 前面三个函数是对象的比对,hash码,和属性的输出,kotlin的不同点是属性的输出会自动将主构造函数中的属性输出不需要重写,同时对象的比对也仅是比对主构造函数中的属性。
* kotlin会为数据类的主构造函数中的每一个属性创建一个函数即:componentN(): n是主构造函数中声明的属性的顺序。
* copy函数用于对象的复制,复制对象的过程中可以修改主构造函数中的属性的值。
* 自动生成的几个函数的数据类中的属性需要满足的必要条件是:
数据类
* 针对比对等三个函数,若数据类中有实现或者父类中有这final的实现则不会自动生成。
* 如果超类存在 open 的 .componentN() 函数, 并且返回一个兼容的数据类型, 那么子类中对应的函数会自动生成, 并覆盖超类中的函数. 如果超类中的函数签名不一致, 或者是 final 的, 导致子类无法覆盖, 则会报告编译错误.
* 不允许对 .componentN() 和 .copy() 函数提供明确的实现(译注, 这些函数必须由编译器自动生成).
-
- 数据类自动生成函数仅对主构造函数的所有属性起作用,对类中声明的属性不起作用,所以常规开发中要么所有属性都在主构造函数声明,要么重写自动生成函数将其他属性添加。同时对象的比对也仅是比对主构造函数中的属性。
* kotlin针对主构造函数中的所有属性生成了对应的componentN函数。 -
解构声明:将对象解构为多个变量,在kotlin中成为解构声明,即声明多个变量,然后将对象直接赋值给声明的多个变量,通常声明的变量名字和对象的属性名字一致(kotlin解构是通过属性名字和变量名字匹配的)即:
数据类解构
- 解构针对的是数据类的主构造函数中的属性,也只有这些属性才会自动生成对应的组件函数。
-
解构也用在for循环中,即对集合的解构:上面的代码将遍历集合中的所有元素, 然后对各个元素调用 component1() 和 component2() 函数, 变量 a 和 b 将得到 component1() 和 component2() 函数的返回值.
集合的解构声明
- 解构声明中的几种常用的案例:
-
从一个函数返回两个值:归根结底是函数返回一个对象,对象包含两个属性,这两个属性解构成为两个值变量,和java中的对象使用两个值一致,即:
解构声明用于函数
-
如上解构声明在map中的使用:
解构声明用于map
-
用下划线_代替解构后的对象的没有使用的值:对象可能声明多个属性,解构后声明值变量的时候若某一个值用不到则可以用下划线标识,这样简化了语法,不用再每一个属性都给其写个名字。
下划线替代未使用的变量
- lambda中使用解构声明:多使用kotlin中的集合的遍历函数中,其函数需要一个lambda表达式,lambda表达式的参数若是一个集合,则其遍历可以直接解构为key和value 再其函数体中可以直接使用这两个值变量。
-
这个使用语法比较多,详细解释一下:lambda表达式语法:参数->函数体,则其参数是一个map或者list集合,map和list集合遍历可以获取其key和value,而解构又可以直接将map或者list遍历成为key和value,所以lambda表达式的参数直接使用(key,value)则是因为其已经进行了解构。
lambda表达式
lambda表达式2
lambda表达式3
-
-
- 封闭类和封闭接口:封闭类和封闭接口是限制了类和接口的实现类(子类)的实现位置,即将其子类的实现位置控制在封闭类的声明包和模块中,比如创建异常模块非常试用封闭类或者封闭接口:error顶层类或者接口,其子类都在这一模块中,其他模块不能够对其进行实现,这个是策略模式特别是编译前穷尽策略模式的最恰当实现。
- 由于封闭类或者接口都在统一模块中实现,所以在编译阶段其子类实现就能够确定。
- 封闭类是抽象类,可以声明抽象函数和抽象属性
- 封闭类在语法上使用关键字:sealed进行声明
- 封闭类的构造函数的权限是protected和private
- 封闭类和接口的直接子类必须定义在同一个包之内. 可以是顶级位置, 也可以嵌套在任意多的其他有名称的类, 有名称的接口, 或有名称的对象之内. 子类可以设置为任意的 可见度, 只要它们符合 Kotlin 中通常的类继承规则.
- 这些限制不适用于非直接子类. 如果封闭的类一个直接子类没有标记为封闭, 那么它可以按照其修饰符允许的方式任意扩展:
- 封闭类的主要好处是体现在
when
表达式中的使用场景. 如果能够确保when
的分支已经覆盖了所有可能的情况, 你可以不必添加else
分支:
封闭类
-
嵌套类(接口):和java一致,kotlin同样支持类中嵌套类,接口中嵌套接口,类中嵌套接口,接口嵌套类,嵌套即在类中声明另外一个类。使用如下:
类嵌套
接口嵌套
- 内部类:
-
内部类是嵌套类的实现,即在嵌套类的实现中使用关键字inner 声明,此类为外部类的一个内部类,此时内类中可以访问外类的属性及其函数。
内部类
- 关于kotlin中的this,可以参考后续的学习整理,即属性和函数中会描述这个,kotlin支持this声明标签进而标识this指向那一个对象。
-
匿名内部类,内部类的一种简化实现,具体语法参考下面图片:
匿名内部类
单实现函数接口的lambda表达式实现
-
- 枚举类:
- java枚举:针对逻辑中的多条件场景,特别是ifelse和switch中 的12345等多场景下,java提供了枚举类,通过枚举中针对每一个数字声明一个对象的方式规范且明了的优化当前场景。下面简单整理一下java枚举中的要点:详情可以参考下面的文章:
- 枚举借助于enum关键字,没有添加任何方法的前提下每一个枚举值都是从0开始
- 枚举默认添加了下面几个方法:values(),name(),ordinal(),getDeclaringClass(),equals()。
- 枚举继承与系统类Enum所以枚举类不能够再继承其他类,但是可以实现其他接口。
- 枚举内部可以声明属性,且可以添加方法:普通方法,静态方法,抽象方法,构造方法,实现接口可以在枚举中实现方法,也可以在枚举的每一个枚举值中实现方法。
- kotlin枚举类:和java一致,kotlin也提供了枚举的支持。
- 普通枚举的实现kotlin和java一致,且kotlin可以通过主构造函数为枚举值赋值。kotlin中枚举中的每一个常数被称为枚举常数。
- 和java一致,kotlin的每一个枚举常数都可以声明一个匿名类,在匿名类中可以声明函数,且函数也可以实现枚举基类声明的抽象函数等。
- 语法上,枚举常数之间使用,隔开,但是枚举中若声明了对应的函数那么枚举常量和函数之间使用;隔开。
- kotlin:枚举可以实现接口不能再继承其他的类。
-
和java枚举系统提供方法一样,kotlin也提供了常数:用来获取枚举常量及其枚举常量对应的值。
枚举系统常数
- java枚举:针对逻辑中的多条件场景,特别是ifelse和switch中 的12345等多场景下,java提供了枚举类,通过枚举中针对每一个数字声明一个对象的方式规范且明了的优化当前场景。下面简单整理一下java枚举中的要点:详情可以参考下面的文章:
- 内联值类:?????????? 没学明白,后续搞明白再来填补。
参考文章:
一文了解java枚举
网友评论