kotlin泛型

安安安安卓 2021-08-15 18:16:51 阅读数:317

本文一共[544]字,预计阅读时长:1分钟~
kotlin

“這是我參與8月更文挑戰的第5天,活動詳情查看: 8月更文挑戰

泛型使用方法

在類上使用泛型

類上面使用泛型,需要把泛型聲明在類名後,使用尖括號錶示


class C1<T>{
fun print(t:T){
print(t.toString())
}
}
複制代碼

泛型函數

在fun關鍵字後使用聲明

fun <T> method1(t:T):String{
println(t.toString())
return t.toString()
}
複制代碼

型變

Java的型變

Java是不型變的,可以這麼理解:

List<String> 並不是 List<Object>

舉例如下代碼是不可以編譯通過的,因為無法型變

interface Collection<E> …… {
void addAll(Collection<E> items);
}
void copyAll(Collection<Object> to, Collection<String> from) {
to.addAll(from);
// Collection<String> 不是 Collection<Object> 的子類型
}
複制代碼

kotlin協變

kotlin的協變使用out關鍵字錶示,而java的協變用? extends E錶示

如果一個類的泛型使用了協變<out T>,則T類型只能做為方法的返回值,不可以做為方法的形參。

舉例:下面的代碼中我們調用Factory.getCar最終獲取的都是Car的類型,是安全的

open class Car{
}
class Taxi: Car() {
fun drive(){
println("開汽車")
}
}
class Truck: Car() {
fun drive(){
println("開卡車")
}
}
class Factory<out T>(private val car:T){
fun getCar():T{
return car
}
// fun setCar(t:T){//這個方法編譯報錯,因為T是協變的,所以只能獲取(被消費),不能設置(被生產)
// this.car=t
// }
}
複制代碼

kotlin逆變

kotlin的逆變用in關鍵字錶示,而java的逆變用? super E錶示

同樣用上面協變的代碼舉例,將T加上in修飾後,泛型就變為逆變的,此時Factory方法中getCar方法就會編譯器報錯,因為逆變的類型只能設置(被生產),不能獲取(被消費)


open class Car{
}
class Taxi: Car() {
fun drive(){
println("開汽車")
}
}
class Truck: Car() {
fun drive(){
println("開卡車")
}
}
class Factory<in T>(private var car:T){
// fun getCar():T{//Type parameter T is declared as 'in' but occurs in 'out' position in type T
// return car
// }
fun setCar(t:T){//這個方法編譯報錯,因為T是協變的,所以只能獲取(消費),不能設置(生產)
this.car=t
}
}
複制代碼

上界

Java和Kotlin指定上界的方式

  • Java中泛型上界的錶示方式:
Foo<T extend Noo>//錶示泛型T是Noo的子類型
複制代碼
  • Kotlin中泛型上界的錶示方式
Foo<T : Noo>//錶示泛型T是Noo的子類型
複制代碼

Kotlin 方法中指定多個上界

kotlin可以使用where關鍵字實現方法中泛型指定多個上界 示例代碼如下:

open class A{
}
interface B{
}
class C: A(),B{
}
class D: A() {
}
fun <T> copy(t:T,list:MutableList<T>) :List<A>
where T:A,
T:B{//where T:A,T:B 錶示泛型T有兩個上界A和B,其中A和B之中A是一個類B是接口,也就是說指定兩個上界的時候只能有一個上界是類
list.add(t)
return list
}
fun main() {
val list = mutableListOf<C>()
copy(C(),list)//因為C同時是A和B的子類,所以這裏編譯可以通過
// copy(D(),list)//因為D是A的子類,不是C的子類,所以這裏編譯器會直接提示錯誤
}
複制代碼

關注我的公眾號 “安安安安卓” 學習更多知識

版权声明:本文为[安安安安卓]所创,转载请带上原文链接,感谢。 https://gsmany.com/2021/08/20210815181419031w.html