/**
* 1泛型Animal 是Father的父类,Son1的父类的父类
* 2泛型Father 是Animal的子类,Son1的父类
* 3泛型Son1 是Father的子类
*/
open class Animal(var name :String){}
open class Father(name : String) : Animal(name){}
class Son1(name: String):Father(name){}
一. 协变out
1.1
/** 协变 out*/
interface GetClass<out T>{
/*** 错误写法*/
// fun get(pargma:T) : T //out只用去读取,因此不可以做参数去修改,但可以作为返回值去接收
/**正确写法*/
fun get() : T
}
1.2
/**
* out相当于Java的<? extends xx>
*/
class GetClassImp1 : GetClass<Animal> {
override fun get(): Animal {
return Animal("Animal")
}
}
class GetClassImp2 : GetClass<Father>{
override fun get(): Father {
return Father("Father")
}
}
class GetClassImp3 : GetClass<Son1>{
override fun get(): Son1 {
return Son1("Son1")
}
}
//out:相当于java的<? extends T>,可以接收T和T的子类
//协变 相当于父类可以接收子类
var g1 : GetClass<Animal> = GetClassImp1()
var g2 : GetClass<Father> = GetClassImp2()
//var g3 : GetClass<Father> = GetClassImp1()//错误写法 声明泛型Father 不可以接收具体泛型 Animal(子类不可以接收父类)
println(g1.get().name)
Java例子:
List<CharSequence> list = new ArrayList <String>(); //错误写法
List<? extends CharSequence> list1 = new ArrayList<String>();//正确写法
二. 逆变 in
1.1
/** 逆变 in*/
interface SetClass<in T>{
/**错误写法*/
// fun set(name:String) : T //in只用去修改, 因此不可以作为返回值去接受,但可以作为参数去获取然后修改
/**正确写法*/
fun set(pargma : T)
}
class SetClassImp1 : SetClass<Animal> {
override fun set(pargma: Animal) {
}
}
class SetClassImp2 : SetClass<Father> {
override fun set(pargma: Father) {
}
}
class SetClassImp3 : SetClass<Son1> {
override fun set(pargma: Son1) {
}
}
var i1 : SetClass<Animal> = SetClassImp1()//正确写法
var i2 : SetClass<Son1> = SetClassImp1()//正确写法,可以接收父类
var i3 : SetClass<Animal> = SetClassImp2()//错误写法 声明泛型Animal 不可以接收具体泛型 Father(父类不可以接收子类)
i1.set(Animal("Animal"))
对比Java
List<String> list2 = new ArrayList<CharSequence>(); //错误写法
List<? super char> list3 = new ArrayList<CharSequence>(); //正确写法
三.总结
协变out :
1.用于读取操作,得作为返回值,不可以作为参数,类比get()
2.声明泛型时,相当于Java的<? extends T>,可以接收T和T的子类
逆变in:
1.用与修改操作,得作为参数去进行修改,不可以作为返回值,类比set()
2.声明泛型时,相当于Java的<? super T>,可以接收T和T的父类