對象表達(dá)式、單例與伴生對象(靜態(tài)對象、靜態(tài)方法)

非常有用的對象表達(dá)式

在java開發(fā)中,需要頻繁聲明很多回調(diào)接口,這些回調(diào)接口通常是內(nèi)部一次性, 我們經(jīng)常會使用匿名的方式創(chuàng)建對象。而kotlin也支持這種方式。

在java中,我們經(jīng)常會這么使用一個接口

interface ISay {
   void sayHello();
  }

ISay say = new ISay() {
   @Override
   public void sayHello() {
       //TODO
          }
   };

在kotlin中,我們可以使用匿名類對象解決這個問題,使用object關(guān)鍵字代表一個匿名內(nèi)部類型,可以訪問其作用域中所有變量,上面的語言翻譯過來可以是:

  var say = object : AnonymousObjectTest.ISay { 
        override fun sayHello() {
            TODO("not implemented") 
        }
    }

而且kotlin支持多繼承匿名類型,超級牛逼

abstract class Listen(ear: Int) {

    abstract fun listen()
}

  var person =object:AnonymousObjectTest.ISay,Listen(2){
        override fun listen() {
            TODO("not implemented")
        }

        override fun sayHello() {
            TODO("not implemented") 
        }
    }

還有一種情況,我們也可以定義一個任意的匿名對象 而不額外聲明任何的類,但是這個對象的作用范圍只存在于作用域內(nèi), 超過作用域則無法訪問定義的屬性

fun foo() {
    val adHoc = object {
        var x: Int = 0
        var y: Int = 0 
  }
    print(adHoc.x + adHoc.y)
}

單例

kotlin可以非常方便的聲明一個單例, 我們可以通過object聲明一個全局的對象。建議這里理解成對象,不要理解為,否則在使用上會與類的靜態(tài)方法產(chǎn)生差異。


abstract class Listen(ear: Int) {
    abstract fun listen();
}

object SingleInstace : Listen(2) {
    override fun listen() {
        System.out.println("hear the world!!")
    }
}

fun main(args: Array<String>) {
    SingleInstace.listen()
}

那么靜態(tài)類和靜態(tài)方法應(yīng)該如何定義呢?我們馬上開講

靜態(tài)類與靜態(tài)方法

kotlin可以使用伴生對象定義靜態(tài)對象與靜態(tài)方法。和它的伴生對象可以相互訪問私有特性,使用companion object關(guān)鍵字修飾, 它的初始化是在相應(yīng)的類被加載(解析)時進(jìn)行的

class CompanionClassSimple {
    val a = 1
    init {
        println("加載類實例") //初始化測試:在類實例化時被加載,加載時機(jī)晚于其伴生對象
    }
    companion object {
        init {
            println("加載伴生對象")  //初始化測試:伴生對象將在類被加載時創(chuàng)建,最先打印
        }
        var b = 1  //靜態(tài)屬性 相當(dāng)于 static int b = 1 

        val c=2 //只讀靜態(tài)屬性 相當(dāng)于final static int b = 1 

        fun plus(x: Int): Int {  //靜態(tài)方法:相當(dāng)于 public static int plus(int x) 
            return x + b
        }

    }
}

fun main(args: Array<String>) {

    var foo = CompanionClassSimple()
    // foo.b  是非法調(diào)用,伴生對象的屬性無法被類實例調(diào)用
    //foo.plus(1) 是非法調(diào)用,伴生對象的屬性無法被類實例調(diào)用

    println("像java一樣調(diào)用靜態(tài)對象:${CompanionClassSimple.b}")  

    println("像java一樣調(diào)用靜態(tài)方法:${CompanionClassSimple.plus(1)}")

    //全局唯一性
    Thread(object : Runnable {
        override fun run() {
            while (true) {
                Thread.sleep(1_000)
                CompanionClassSimple.b++   //每一秒新增一次
            }
        }
    }).start()

    Thread(object : Runnable {
        override fun run() {
            while (true) {

                Thread.sleep(2_000)
                System.out.println(CompanionClassSimple.b) //每兩秒打印一次
            }
        }
    }).start();
    readLine()
}
  1. 伴生對象的成員看起來像其他語言的靜態(tài)成員,在運(yùn)行時他們?nèi)匀皇?code>真實對象
    實例成員

  2. 該對象實現(xiàn)可以實現(xiàn)接口,例如 companion object : Runnable()

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容