转载

Koltin第六讲---类与类的映射

内容简介
前面讲了 Kotlin 是如何定义一个类,我们发现与 Java 还是存在很多不同。今天我们来讲解下 Kotlin 中都有什么样的类,以及如何定义呢?  
讲解前大家想想 Java 中有什么样的类呢?普通类丶抽象类丶非静态内部类丶静态内部类丶匿名内部类丶枚举类,我想大家应该对这些类都在熟悉不过了吧?Kotlin 中也存在这些类只是定义方式不同罢了,并且 Kotlin 中新增了部分类(密封类 丶 Data类丶单例类)。

静态内部类

静态内部类,定义在一个类里面,主要特点就是不持有外部类的引用。  Kotlin  中如何定义呢?

反编译的代码:

我们看看反编译的  Java  代码,可以发现  Kotlin  中默认定义的内部类就是静态内部类(刚好与  Java  相反)。 还发现定义的静态内部类是被  final  修饰的,也就是说不可以被继承的,那如何让其可以继承呢? 通过  open  修饰即可啦。

非静态内部类

非静态内部类,持有外部类的引用(小心内存泄漏哦)。  Kotlin  中只需要通过  inner  修饰符,修饰内部类即可。

反编译的代码:

通过上面的  Java  的代码可以清晰的看出内部类,没有被  static  修饰。

匿名内部类

匿名内部类,在  Android  中经常被使用,例如我们经常一个方法的参数接收一个接口的类型或者抽象类对象,我们以前都会直接通过  new  关键词,直接创建一个无名类的对象,并实现其对应方法。

其实匿名内部类,并不是没有名字的。 在编译后也会生成  class  文件,类名会定义成  外部类昵称$N  (这里的N是一个数字,数字依次递增表示多个匿名内部类)。

我们看到  Kotlin  中定义匿名内部类不再是通过  new  关键词来定义了? 而是使用  object  来定义,并且若抽象类具有构造函数,一定要传入对应构造参数。 (大家想想 object 关键词还在那里用到过呢? )

我们来看看生成的  class  文件。

Koltin第六讲---类与类的映射

的确是生成了2个  class 文件,奇怪怎么和我说的  外部类昵称$N  结果不一样呢? 我特意在写了一个  Java  类。

接下来,我通过  ApkTool  反编译了下,直接看  smali  文件更为的直接。 看下图  Java  的确是这样命名规则,但是  Kotlin  规则变了  外部类昵称$接收对象昵称$N (应该是  Kotlin  编译器搞的鬼吧)。

为何纠结这个问题呢? 因为有时候我想反射创建匿名内部类对象的时候,会用到这个知识点。

Koltin第六讲---类与类的映射

枚举类

枚举类和  Java  是一样的,并且支持使用  when  语句。

单例类

在  Java  中单例设计模式是常见的一种设计模式了,常见的单例有 懒汉丶饿汉丶枚举单例丶静态内部类单例,以前写单例这种搬砖代码,我都是添加一个代码模板。  Kotlin  语言开发者似乎也头疼这个问题,为我们专门定义了一种单例类。  Kotlin  中只需要通过  object  修饰类即可。

是不是超级简单?那 它属于什么样的单例呢? 我们看下反编译后的  Java  代码,原来是饿汉式单例。 大家试想下  Kotlin  如何定义一个懒汉式的单例呢? (提示:伴生对象

data 类

在  Java  中是不是经常定义实体对象呀,然后重写其  get  丶  set  丶  toString 丶  hashCode 丶  equals  等方法。  Kotlin  再也不用这么复杂了,只需要通过  data  修饰类即可。

看下反编译结果:

通过上面的反编译代码,发现还是重写了很多方法,并且定义了  copy  方法。(深拷贝呢? 还是浅拷贝呢?

这里补充下  componentN  方法,这个类似一个操作符重载,后续会 讲到 。 其实在测试用例中,我演示过用法  val(name,time)=play  快速创建了2个  name  和  time  变量,并且将  play  对象中的  component1  和  component2  方法返回值将其赋值。 这个是不是很眼熟呀? 没错集合遍历的时候用到这个点了。

密封类

密封类定义  sealed  修饰,密封类定义有限个数的子类,并且限制定义范围(不包含间接继承,和  Java  中的枚举有异曲同工之处。

密封类与枚举类存在本质区别,密封类是注重子类个数,枚举类注重的是有限对象个数。 那密封类有什么好处呢? 举个例子:用户场景,分为3种用户 普通会员丶 会员丶 超级会员,我们每种会员都有对应的特殊功能,所有的会员都要是  User  的子类。 以前我们可以通过枚举定义这种会员类型,但是不能对其定制特定的方法与属性,在  Kotlin  中可以用密封类来代替。

补充下:在 Kotin1.1 修改了密封类的继承范围,只需要在同一个 kt 文件都可以继承。

知识点:  sealed 修饰的类为何不能  new 呢?其实  Kotlin 编译器搞的鬼,将密封类编译成一个抽象类,所以无法直接创建对象。

类的映射 typealias

这是个补充点,为何 放在 类 篇章呢? 因为它和类有一定关系。 还记得集合篇章我说过  Kotlin  并没有重复造轮子,完全使用的  Java  中的集合。 怎么实现的呢? 其实就是通过  typealias  关键词。

其实  typealias  关键词主要在告诉编译器,编译到我定义的  KotlinFile  请给我替换成  File 。

接下来看看, Kotlin 中定义的集合映射吧!大伙想没想过为啥要这样做呢?个人理解为了解耦,假如有一天  Kotlin 想造轮子了,为了保证以前的代码不用更改,只需要修改映射关系即可。

推荐阅读

Koltin第六讲---类与类的映射

Koltin第六讲---类与类的映射

--END--

识别二维码,关注我们

Koltin第六讲---类与类的映射

原文  http://mp.weixin.qq.com/s?__biz=MzUyODg5NDg3NQ==&mid=2247484059&idx=1&sn=050e4ec887b1f1998c42561506b31ea2
正文到此结束
Loading...