泛型類和函式
型別引數約束
泛型允許定義帶型別形參的型別,當這種型別的例項被建立出來的時候,型別形參被替換成稱為型別實參的具體型別例項
// 原始碼listof函式宣告
funlistof
(vararg elements: t)
: list
val list=
listof
("hello"
,"world"
)// 編譯器推導
val list= listof()
// 顯示說明
上例中t為型別形參 ,並且函式的返回型別使用了型別形參
區別
kotlin 通過在類名稱後加上一對尖對號,並把型別引數放在尖對號內來宣告泛型類及泛型介面。一旦宣告之後,就可以在類的主體內像其他型別一樣使用型別引數。
// 泛型類
class gen
(private
var t: t)
}// 泛型介面
inte***ce list
小結:如果類繼承了泛型類(實現了泛型介面),就得為基礎型別的泛型形參提供了乙個型別實參,它可以是具體型別或者另乙個型別形參:
class genlist:list
class arraylist
:list
泛型函式有它自己的型別形參,這些型別形參在每次函式呼叫時都必須替換成具體的型別實參
fun
printmessage
(msg :t)
else
->
}}
注意:普通(即非拓展)屬性不能擁有型別引數,不能在乙個類的屬性中儲存多個不同型別的值,因此宣告泛型非拓展函式沒有任何意義
型別引數約束可以限制作為泛型類和泛型函式的型別實參的型別;如果把乙個型別指定為泛型型別形參的上界約束,在泛型型別具體的初始化中,其對應的型別實參就必須是這個具體型別或者它的子型別示例
// 函式宣告
fun list
.sum()
:t// 具體型別實參繼承了number,函式呼叫是允許的
println
(listof(1
,2,3
).sum(
))
上例中,通過在型別引數後指定上界來定義約束,把冒號放在型別引數名稱之後,作為型別形參上界的型別緊隨其後;一旦指定了型別形參t的上界,就可以把型別t的值當作它的上界(型別)的值使用
型別引數非空、可空
如果宣告的是泛型類或者泛型函式,任何型別實參,包括那些可空的型別實參,都可以替換它的型別形參;沒有指定上界的型別形參將會使用any?這個預設上界
// 型別引數可空 預設上界的型別形參是any?
class person
}// 型別引數非空 預設上界的型別形參是any
class person
}
注意:可以通過指定任意非空型別作為上界,來讓型別引數非空,不光是型別any 學習Kotlin之泛型實化
j a中是沒有泛型實化這個概念的,不過為了深刻理解泛型實化,還需要了解一下j a的泛型擦除機制。在jdk 1.5之前,j a是沒有泛型功能的,那個時候諸如list之類的資料結構可以儲存任意型別的資料,取出資料時也要手動向下轉型,不僅麻煩,還很危險。於是在jdk 1.5中,j a引入了泛型功能。實際上...
泛型之泛型類
public class a 構造引數型別上使用泛型 public a t t 方法返回值上使用泛型 public t gett 方法的引數上使用泛型 這是泛型類的方法,而不是泛型方法 public void sett t t 方法的返回值和引數型別上使用泛型 public t foo t t pu...
泛型之泛型類
public class a 構造引數型別上使用泛型 public a t t 方法返回值上使用泛型 public t gett 方法的引數上使用泛型 這是泛型類的方法,而不是泛型方法 public void sett t t 方法的返回值和引數型別上使用泛型 public t foo t t pu...