泛型是高階程式設計語言中強大的功能,允許定義使用不同型別存取的類,方法和屬性等。 在編譯時檢查類,方法等的型別差異。
泛型類或類宣告為引數化型別。 引數化型別是具有實際型別引數的泛型型別的範例。 引數化型別使用尖括號宣告<>
泛型主要用於集合。
以下是使用泛型的主要優點:
下面來看看在不使用泛型的情況下的存在的一些問題。
在此範例中,使用具有單個引數的主建構函式建立Person
類。 現在,要在Person
類的物件中傳遞不同型別的資料(比如Int
型別為Person(30)
,String
型別為Person("40")
)。 Person
類的主要建構函式接受Int
型別Person(30)
,但是又想接受String
型別的Person("40")
。它會在型別不匹配時生成編譯時錯誤。
class Person (age:Int){
var age: Int = age
init {
this.age= age
println(age)
}
}
fun main(args: Array<String>){
var ageInt: Person = Person(30)
var ageString: Person = Person("30")// 編譯時出錯
}
為了解決上述問題,使用泛型類,這是一個使用者定義的類,它接受單個類中不同型別的引數。
使用泛型型別重寫上面的程式碼。 型別為<T>
的Person
是一個通用型別類,它接受Int
和String
型別的引數。
換句話說,型別引數<T>
是一個預留位置,它將用實際的型別引數替換。它將在範例化泛型型別時替換。
class Person<T>(age: T){
var age: T = age
init {
this.age= age
println(age)
}
}
fun main(args: Array<String>){
var ageInt: Person<Int> = Person<Int>(30)
var ageString: Person<String> = Person<String>("40")
}
執行上面範例程式碼,得到以下結果 -
30
40
在上面的範例中,當使用型別Int
作為Person <Int>(30)
和Person <String>("40")
建立Person
類的物件時,它將分別用Int
和String
替換Person
類的T
型別。
泛型語法
class_or_interface<Type>
泛型方法的語法
<Type>methodName(parameter: classType<Type>)
下面來看看一個泛型方法的範例。 在此範例中,存取集合型別的泛型方法(ArrayList
)。 分別為String
和Float
型別建立ArrayList
類arrayListOf <String>("Maxsu","Yiibai")
和arrayListOf <Float>(10.5f,5.0f,25.5f)
的兩個不同型別物件。 當使用printValue(stringList)
呼叫泛型方法<T> printValue(list:ArrayList <T>)
時,方法<T> printValue(list:ArrayList <T>)
的型別T
將自動替換為String
型別。 類似地,當使用printValue(floatList)
呼叫泛型方法時,方法<T> printValue(list:ArrayList <T>)
的型別T
將自動替換為Float
型別。
fun main(args: Array<String>){
val stringList: ArrayList<String> = arrayListOf<String>("Maxsu","Yiibai")
val s: String = stringList[0]
println("列印 stringList 的字串值: $s")
printValue(stringList)
val floatList: ArrayList<Float> = arrayListOf<Float>(10.5f,5.0f,25.5f)
printValue(floatList)
}
fun <T>printValue(list: ArrayList<T>){
for(element in list){
println(element)
}
}
執行上面範例程式碼,得到以下結果 -
列印 stringList 的字串值: Maxsu
Maxsu
Yiibai
10.5
5.0
25.5
由於擴充套件函式允許向類新增方法,而不繼承類或任何設計模式。
在這個例子中,將一個方法printValue()
新增到泛型型別的ArrayList
類中。對就於String
和Float
型別的方法分別為stringList.printValue()
和floatList.printValue()
。 擴充套件函式中的this
關鍵字表示當前呼叫範例。 當使用stringList.printValue()
呼叫擴充套件函式時,this
表示包含String
型別值的stringList
範例。 類似地,使用floatList.printValue()
呼叫擴充套件函式時,this
表示包含Float
型別值的floatList
範例。
fun main(args: Array<String>){
val stringList: ArrayList<String> = arrayListOf<String>("Maxsu","Yiibai")
stringList.printValue()
val floatList: ArrayList<Float> = arrayListOf<Float>(10.5f,5.0f,25.5f)
floatList.printValue()
}
fun <T>ArrayList<T>.printValue(){
for(element in this){
println(element)
}
}
執行上面範例程式碼,得到以下結果 -
Maxsu
Yiibai
10.5
5.0
25.5