扩展

作者: Green_Apple | 来源:发表于2017-09-01 09:35 被阅读0次

    package tuozhan

    /*
    Kotlin 可以对一个类的属性和方法进行拓展,且不许需要继承或者使用Decorator模式
    拓展是一种静态行为,对被拓展的类代码本身不会造成任何影响
    /
    //---------------拓展函数--------------
    /

    receiverType:表示函数的接受者,也就是函数拓展的对象
    function:拓展函数的名称
    params:拓展函数的参数,可以为NULL
    fun receiverType.functionname(params){
    body
    }*/

    class User(var name:String)
    //拓展函数
    fun User.Print(){
    println("用户名:$name")
    }

    fun MutableList<Int>.swap(index1:Int ,index2:Int){
    //this对应该列表的实例
    val tmp=this[index1]
    this[index1]=this[index2]
    this[index2]=tmp
    }

    fun MutableList<Int>.add(){
    println("决定静态调用么?")
    }

    /*fun main(arg:Array<String>){
    var user=User("彭伟伦")
    user.Print()
    val l=mutableListOf(1,2,3)
    l.swap(0,2)
    println(l.toString())
    l.add()
    }
    */

    //-----------扩展函数是静态解析的---------
    /*
    扩展函数是静态解析的,并不是接受者类型的虚拟成员,在调用扩展函数时
    具体被调用的是哪一个函数,有调用函数的对像表达式决定,而不是动态的类型决定
    /
    /

    open class C
    class D:C()
    fun C.foo()="c" //拓展C的函数
    fun D.foo()="d" //扩展D的foo函数
    fun printFoo(c:C){
    println(c.foo()) //类型是C类
    }

    若扩展函数和成员函数一致时,会优先使用成员函数

    class P{
    fun foo(){
    println("成员函数")
    }
    }

    fun P.foo(){
    println("扩展函数")
    }

    fun main(args: Array<String>) {
    printFoo(D())
    var p=P()
    p.foo()
    }*/

    //----------扩展一个空对象---------------
    /*
    在扩展函数中,可以通过this来判断接收者是否为NULL,这样,即使接受者为NULL
    也可以调用扩展函数
    */
    fun Any?.toString():String{
    //this 代表当前调用的对象也是接收者
    if(this==null) return "null"
    //判断为null之后,this会被自动转换为非空类型,所以下面的toString解析为Any的成员函数

    return toString()
    

    }

    /*
    扩展属性
    除了函数,Kotlin也支持属性对属性进行扩展
    扩展属性允许定义在类或者Kotlin文件中,不允许定义在函数中,
    初始化属性没有后端字段 所以不允许被初始化,只能由显示提供的getter/setter定义
    */
    val<T> List<T>.lastIndex:Int
    get()=size-1

    /*fun main(args: Array<String>) {

    var t=null
    println(t.toString())
    var l=listOf<Int>(1,2,3)
    println(l.lastIndex)
    var l2=ArrayList<Int>()
    println(l2.size)
    

    }*/

    //-------------伴生对象的扩展-----------
    /*
    如果一个类定义有一个伴生对象,你也可以为伴生对象定义扩展函数和属性
    伴生对象通过“类名” 形式调用伴生对象,伴生对象声明的扩展函数,通过类名限定符来调用
    */
    class MyClass{
    companion object{}
    }

    fun MyClass.Companion.foo(){
    println("伴生对象的扩展函数")
    }

    val MyClass.Companion.no:Int
    get()=10
    /*
    fun main(args: Array<String>) {
    println("no:${MyClass.no}")
    MyClass.foo()
    }*/

    //-------扩展的作用域----------
    /*
    package foo.bar

    fun Baz.goo() { …… } 
    要使用所定义包之外的一个扩展, 通过import导入扩展的函数名进行使用:
    package com.example.usage
    
    import foo.bar.goo // 导入所有名为 goo 的扩展
                       // 或者
    import foo.bar.*   // 从 foo.bar 导入一切
    
    fun usage(baz: Baz) {
        baz.goo()
    }
    

    */

    //------------扩展声明为成员----------------
    /*
    在一个类的内部,你可以为另一个类声明扩展
    在这个扩展中,有多个隐含的接受者,其中扩展方法定义在类的实例称为分发者
    而扩展方法的目标类型的实例称为扩展接收者
    /
    /
    class D{
    fun bar(){println("D bar")}
    }

    class C{
    fun baz(){println("C baz")}

    fun D.foo(){
        bar()
        baz()
    }
    
    fun caller(d:D){
        d.foo()//调用扩展函数
    }
    

    }/
    /

    在C类内,创建了D类的扩展函数,此时C被称为分发接收者,而D为扩展接收者
    在此类扩展函数中,可以调用派发接收者的成员函数
    假如在调用某个函数,而该函数在分发接收者和扩展接收均存在,要引用分发接收者的成员
    你可以使用限定的this语法
    */

    /*fun main(args: Array<String>) {
    val c:C=C()
    val d:D=D()
    c.caller(d)
    }
    */

    /*
    以成员的形式定义的扩展函数,可以声明为open ,而且可以在子类中覆盖,也就是说
    在这类扩展函数的派发过程中,针对分发接收者是虚拟的,单针对扩展接受者仍是静态的(不会因为传入的对象变化而变化)
    一句话概括就是,该是谁的就是谁的调用

    */

    open class D{}
    class D1:D(){}
    open class C{
    open fun D.foo(){
    println("D.foo in C")
    }
    open fun D1.foo(){
    println("D1.foo in C")
    }
    fun caller(d:D){
    d.foo()
    }
    }
    class C1:C(){
    override fun D.foo(){
    println("D.foo in C1")
    }

    override fun D1.foo(){
        println("D1.foo in C1")
    }
    

    }
    fun main(args: Array<String>) {
    C().caller(D()) //D.foo in C
    C1().caller(D()) // D.foo in C1
    C().caller(D1()) //D.foo in C
    }

    相关文章

      网友评论

          本文标题:扩展

          本文链接:https://www.haomeiwen.com/subject/olehjxtx.html