可见性【Visibility】:
在Java中的可见性有public、protected、private、default四种,而在Kotlin中也有四种:public、protected、private、internal,下面来细说一下:
作用在顶层类及函数上:
像这样直接定义在包下面的则称之为顶层类及函数,如下:
①、我们知道在Java中如果啥都不写就是包级别的default可见性,但是在Kotlin中不是这样的,默认是public的,当然是哪都能使用喽。
②、如果我们将其声明为private,则只能在当前的.kt这个文件中来使用,如下:
③、如果声明为internal,则只能在一个module中可见,其中module的概念就是说当前工程,比如像gradle构造的整个工程既为一个module,如下:
④、关于protected修饰符,它有一个特殊的地方,就是不能用在顶层[top level]的函数及类上,啥叫顶层函数及类,像我们目前定义的就属于这种,如下:
那咱们来试试,看能否在这俩上加protected修饰符:
确实是!!
作用在类里面的函数及属性上:
比如:
总的修饰符的情况如下:
①、如果类里面声明了private,则只能在当前类中进行使用,跟Java一样。
②、如果类里面声明了protected,可以在当前类及子类使用,跟Java也一样。
③、如果类里面声明了internal,如果能使用类,则就可以使用。
④、如果类里面声明了public,任何地方都可用。
下面举个例子再来巩固一下:
其中第一个属性b是私有的,它只能在Clazz当前类使用,不能在子类使用,如下:
而对于c只能在子类subClazz中使用,d也能在subClazz中使用,因为和Clazz是在一个模块的。那如果定义一个不继承的类:
那么对于在Clazz中定义的三个属性,其可见性如下:
关于可性修饰符就学到这,比较简单。
扩展【extension】:
关于扩展这个特性是在Java中没有的,但是其实是在其它有些语言早就已经存在的概念的,如c#,那啥叫扩展呢?在Java中当我们定义好了一个类,如果想要给该类扩充功能有哪些手段呢?继承是很容易想到的一个方式,另外可以利用装饰模式来进行扩充如IO相关的东东。而在Kotlin中可以很轻松的对类进行动态的扩展,下面来感受一下:
很easy,接下来想要完成数字的乘法,很明显是目前我们定的类中不满足的功能,而且这个类不是我们自己写的放到jar包里面,也就是只读,接下来Kotlin的扩展功能就发挥作用了,如下:
是不是很神奇~~其实在Android中的Kotlin开发中会发现这个特性大量被用到的,以上就是关于Kotlin的扩展的使用,比较简单,但是仅仅只是学会用很明显是不够的,接一来看一下它的底层的一些东东。
1、扩展函数的解析是静态的,扩展本身并不会真正修改目标类,也就是说它并不会在目标类中插入新的属性或是方法。
从我们的程序可以看出,是给类动态扩展了一个方法,但是!!!并非我们所理解的那样,是将我们扩展的方法插入到了类中,其实不是这样的,原类拥有的方法还是只有2个,如下:
我不信,不可能~~那下面将其字体码反编译看一下就知道了:
2、 扩展函数的解析是静态分发的,而不是动态的,既不支持多态,调用只取决于对象的声明类型。调用是由对象声明类型所决定的,而不是由对象的实际类型决定。
关于多态,既是用一个父类型的引用来指向子类型的对象,比如回顾一下Java代码:
其中它里面具体是调用哪个a(),是由传给parent参数的实际类型来决定的,如果传过来的是Parent,那么调用的就是Parent.a(),而如果传过来的是Child,那么调用的就是Child.a(),这是一个动态调用,但是!!!!在Kotlin扩展函数的解析是不支持多态的,它只看声明的类型,而不看实际的类型,下面举个具体例子来看一下: