- 顶层函数和顶层属性
- java中的方法都属于声明的类中,但是kotlin支持一种特殊的函数即顶层函数,即在文件的顶层(非类中)直接声明函数。
- 顶层函数的权限是包内权限,在包内可以直接使用,在包外需要import 引入对应的文件,* 代表引入文件内的所有的顶层函数,也可以引入单个顶层函数。
- 顶层函数的使用和其他函数的调用一致。
- java访问kotlin顶层函数:需要在声明顶层函数的文件上通过注解标明java中的类名,java中通过类名访问对象的顶层函数即可
- 顶层函数的原理:kotlin编译成为java文件的时候会为这几个函数生成一个类,这几个函数属于这个类的静态方法,类的权限是默认包内权限,所以可以通过静态方法语法访问。
-
顶层属性和顶层函数的机制一致。
- 扩展函数和扩展属性
- java或者kotlin会针对每个类提供一系列的方法或者函数来提供对应的功能,但是不一定能够提供完全的功能,特别是一些三方的sdk想要提供更多的功能方法java不好处理(通常是继承扩展个子类来完善,允许继承),但是kotlin对于此种场景提供了扩展的机制,通过扩展可以方便的让类提供更多的功能,比如String类,内部已提供了length等功能方法,但是要想反转字符串当前系统是不提供对应的方法和函数的,kotlin支持通过扩展String类来添加一个函数实现这个功能,其他的字符串就可以直接使用这个函数。
- 扩展函数:
-
语法:fun 需要扩展的类.扩展函数(参数) { 函数体}
-
扩展函数的使用:扩展的类对象.扩展函数(实参)
-
扩展函数的使用具体调用那个扩展函数,取决于调用的这个扩展函数所述的扩展类,即扩展函数的直属扩展类,比如父类和子类两个都扩展了同一个名称的扩展函数,外部使用的时候的扩展函数取决于扩展类是父类还是子类,即扩展函数是扩展类的静态函数。
-
扩展函数和扩展类的成员函数是同一个函数的时候,扩展函数失效,扩展类的成员函数优先级大于扩展函数,但是可以同一个函数名不同的参数重载扩展函数。
- 扩展函数的函数体中的this指向的扩展类,通过this可以调用扩展类的成员函数和成员属性。
- java 访问扩展函数的方法:扩展类.扩展函数调用。
-
- 扩展属性:
-
语法:val/var 扩展类.扩展属性名称:扩展属性类型
get() {}
set(value) {}
-
使用:扩展类.扩展属性名称
- 扩展属性没有幕后字段,没有初始化器,必须定义属性访问器。即:扩展属性不能直接初始化即扩展类.扩展属性名称 = 1是不允许的,只能通过声明的set和get访问和设置属性。
- 只能在文件或者类中扩展属性,不能在函数体中扩展属性。
- java对于扩展属性的访问和扩展函数一致,也是通过扩展类.扩展属性访问。
-
- 伴生对象的扩展:
- 语法:fun 扩展类.Companion.扩展函数(参数) { }
-
使用:扩展类.Companion.扩展函数:Companion可以省略。
- 扩展函数:
-
定义扩展函数/扩展属性的位置:通常是在包名下的顶层扩展,通常和顶层函数/顶层属性位置相似。
-
在包内可以直接通过扩展类.扩展函数直接使用,但是若是在包外不能直接使用,需要通过import的方式将扩展函数导入然后通过扩展类.扩展函数使用。
-
-
kotlin:在一个类的内部为另一个类提供扩展函数,那么这个类叫做派发者,另一个类被称为接受者
-
在此种情况下的扩展函数中,倘若派发者和接受者的函数出现冲突,则接受者的函数的优先级要高于派发者的函数,倘若当前想要指明使用派发者的函数则可以通过带限定符的this(就是通过限定符指明当前的this指向那一个对象)指明函数属于派发者的函数,即this@派发者.函数。
-
此种情况的扩展函数可以通过open指定开放,则派发者类的子类可以继承类后重写扩展函数,然而在扩展函数的使用的时候扩展函数的执行依赖于前面的扩展类,前面的扩展类是谁就是谁的扩展函数执行和参数的父子关系无关。
-
- 扩展函数及其其他函数的权限关系:
- 顶层声明 的扩展函数可以访问顶层属性和顶层函数,成员类中声明的扩展函数可以访问成员类中的函数和属性。
- 扩展函数不能访问扩展类中的private或者protected函数和属性,可以访问public权限函数或者属性,同包内可以访问默认权限的函数和属性
- 扩展函数的使用权限是同包内,同包内可以直接调用,不在同包内需要通过import引入扩展函数后才能使用。
参考文章:
kotlin:顶层函数
kotlin: 系统中声明的顶层函数
kotlin: 扩展属性
kotlin:扩展属性和扩展函数