9.Kotlin扩展深入解析及注意事项

1.可见性

可见性 visibility
Kotlin提供4种可见性修饰符: private,protected,internal,public
(1)如果没有指定任何可见性修饰符,则默认使用public,这意味着声明将在任何位置都可见;
(2)如果将一个声明标记为private,那么它只会在包含声明的文件中可见;
(3)如果将其标记为internal,则在同一模块中的任何地方可见;
(4)如果将其标记为protected,则不可用于顶层声明。

  • 示例代码
//顶层声明,不加修饰符默认public
fun method(){

}
class Clazz

对于在类中声明的成员:
(1)private只有在这个类才能看到(包括其所有成员);
(2)protected - 相同于private + 在子类中可见;
(3)internal - 模块中的任何看到声明类的客户端都看到其内部成员;
(4)public - 声明类的任何客户看到它的公共成员。

  • 示例代码
open class Clazz{
    private val b =3;
    protected  open val c = 4;
    internal val d = 5;
}

class subClazz:Clazz(){
    //c、d 可用
}

class Clazz2{
    // d 可用
}
  • 局部变量

局部的变量,函数和类不能有可见性修饰符。

2.扩展

扩展:extension
扩展函数的解析是静态的
(1)扩展本身并不会真正修改目标类,也就是说它并不会在目标类中插入新的属性或是方法
(2)扩展函数的解析式静态分发的,而不是动态的,即不支持多态,调用只取决于对象的声明类型
(3)调用是由对象声明类型所决定的,而不是由对象的实际类型决定。

  • 示例代码

//扩展:extension

class ExtensionTest {
    fun add(a: Int, b: Int) = a + b
    fun subtract(a: Int, b: Int) = a - b
}

fun ExtensionTest.multipy(a: Int, b: Int) = a * b

fun main(args: Array) {
    var extensionTest = ExtensionTest();

    println(extensionTest.add(1, 2))
    println(extensionTest.subtract(1, 2))
    println(extensionTest.multipy(1, 2))

    myPrint(BB())

    CC().foo(1)
}

//扩展函数的解析是静态的
/*
    1.扩展本身并不会真正修改目标类,也就是说它并不会在目标类中插入新的属性或是方法
    2.扩展函数的解析式静态分发的,而不是动态的,即不支持多态,调用只取决于对象的声明类型
    3.调用是由对象声明类型所决定的,而不是由对象的实际类型决定。
 */

open class AA

class BB : AA()

fun AA.a() = "a"
fun BB.a() = "b"

fun myPrint(aa: AA) {
    println(aa.a())
}

//扩展重名
class CC{
    fun foo(){
        println("member")
    }
}

fun CC.foo(i:Int){
    println("member2")
}
//可接受Null的接收器
fun Any?.toString():String{
    if(null == this){
        return "null"
    }

    return toString()
}
  • 运行结果
3
-1
2
a
member2

扩展可以与已有的方法重名,即签名完全一样,这样的情况下,已有方法的优先级别要高。

请注意,可以使用可空(null)接收器类型定义扩展。 这样的扩展可以在一个对象变量上调用,即使它的值为null,并且可以在主体内检查this == null。 这样就可以在Kotlin中调用toString(),而无需检查null:检查发生在扩展函数内。

你可能感兴趣的:(9.Kotlin扩展深入解析及注意事项)