Kotlin 修煉手冊(6)伴生對象

前言

這篇文章來寫一下 Kotlin 中的伴生對象。java

從靜態提及

以前的文章中,提到在 Java 中,使用 static 這個關鍵字來表示在類層面的變量和方法,好比:安全

class HttpUtils{
	public static final String URL = "http://www.baidu.com";
	public static String getHttpResponse(){
		//實現
	}
}
複製代碼

在 Kotlin 中沒有 static 這個關鍵字,也去掉了直接的靜態變量和靜態方法的概念,而是使用伴生對象(companion object)來實現靜態,好比:bash

class HttpUtils{
	companion object{
		const val url = "http://www.baidu.com""
		fun getHttpResponse():String{
			//實現
		}
	}
}
複製代碼

這裏有一些關鍵字:companion、object、const,分別來看看,先來介紹下 objectide

object 關鍵字

在 Kotlin 中沒有大寫的 Object 類,代替它的是 Any 這個類,意思都是全部類的父類。小寫的 object 是一個關鍵字,表明的意思是:建立一個類,同時生成一個這個類的對象。函數

object Test{
	val name = "owen"
	fun printName(){
		println(name)
	}
}

fun main(){
	Test.printName()
	println(Test.name)
}
複製代碼

調用的時候就直接使用 類名.函數/屬性 便可。ui

注意在 Java 代碼中調用這個函數的寫法:url

Test.INSTANCE.printName();
複製代碼

須要加一個 INSTANCE 來進行調用,這其實就是 Kotlin 中單例模式的一種實現。(餓漢式單例,且線程安全)spa

若是想要實如今 Java 中像 Kotlin 同樣直接使用類名調用的話,須要在函數上方加一個 @JvmStatic 註解。線程

object Test{
    val name = "owen"
    @JvmStatic
    fun printName(){
        println(name)
    }
}
複製代碼

Java 代碼中調用:code

Test.printName();
複製代碼

繼承其餘類和實現接口

用 object 建立的類一樣能夠繼承其餘類,實現接口,和 class 是同樣的。

open class PersonA{
    open fun say(){
        println("Person:say")
    }
}
interface MyInterface{
    fun foo()
}
object Test: PersonA(),MyInterface{
    override fun foo() {
        println("Test:foo")
    }
    override fun say() {
        println("Test:say")
    }
}
複製代碼

object 能夠理解爲在用 class 關鍵字來定義類的基礎上,額外實現了單例。

object 實現匿名內部類

在以前《類與對象》一章中也提到 object 關鍵字能夠用來實現匿名內部類。

class Button{
    var text = "文字"
    fun setOnClickListener(listener: OnClickListener){
        listener.onClick()
    }
}

/**
 * 定義接口
 */
interface OnClickListener {
    fun onClick()
}

fun main(){
	var button = Button()
    button.setOnClickListener(object : OnClickListener{
        override fun onClick() {
            println("點擊了button")
        }
    })
}
複製代碼

伴生對象(companion object)

object 中的屬性和函數均可以看做靜態的(事實上函數並非靜態的,只是能夠經過單例進行調用,除非加 @JvmStatic 註解)。爲了實現類中部分屬性和方法是靜態,Kotlin 中容許在類中增長一個伴生對象,用來專門存放靜態屬性和函數。這個伴生對象是和外部類綁定的,而且最多隻能有一個(嵌套類能夠有多個)。

完整的寫法應該是這樣:

class A{
	companion object B{
		val p = 0
		val foo(){}
	}
}
//要用屬性和函數時,這樣寫:
A.B.p
A.B.foo()
//或者直接省略ojbect的類名
A.p
A.foo()
複製代碼

在寫伴生對象時,類名也能夠直接省略。

class A{
	companion object{  //類名B省略
		const val p = 0
		val foo(){}
	}
}
複製代碼

在 Kotlin 中,使用 const 來表示常量,只能用來修飾 val,不能修飾 var。

結語

下一篇是關於 Kotlin 的擴展的相關內容。

參考資料

Kotlin 裏那些「不是那麼寫的」

相關文章
相關標籤/搜索