目录
一、认识
Kotlin的泛型与Java一样,都是一种语法糖,泛型其实就是把类型参数化,它的引入给强类型编程语言加入了更强的灵活性
在Java中,我们常见的泛型有,泛型类,泛型接口,泛型属性,泛型方法,Kotlin泛型继承了Java泛型系统,同时加入了一些强化的地方
泛型的意义:
1、架构开发
2、框架SDK开发
3、增加代码健壮性,避开运行时ClassCastException
二、泛型接口/类
1、泛型接口
面向接口编程
fun main() {
val redApple = Apple()
redApple.drink("red Apple")
}
interface drink<T>{
fun drink(drink: T)
}
class Apple : drink<String>{
override fun drink(drink: String) {
print("drink:$drink")
}
}
2、泛型类
面向对象编程
泛型父类可以使用abstract抽象类的抽象方法,
fun main() {
val circle = Circle("circle")
println( circle.name)
circle.shape()
}
abstract class Shape<T>(t: T){
abstract fun shape()
}
class Circle(val name: String) : Shape<String>(name){
override fun shape() {
print("shape $name")
}
}
也可以使用普通类的open 关键字来声明。
fun main() {
val circle = Circle()
circle.shape("circle")
}
open class Shape<T>{
open fun shape(t: T) {}
}
class Circle : Shape<String>(){
override fun shape(t: String) {
print("shape $t")
}
}
三、泛型字段
一般用在方法参数括号里(),跟随类的声明,比如构造方法中
abstract class Color<T>(t: T){
abstract fun draw()
}
四、泛型方法
类型参数要在方法名字前面
fun main() {
val person:Person ? = fromJson<Person>("json",Person::class.java)
}
fun <T> fromJson(json:String,mClazz:Class<T>):T?{
val t:T? = mClazz.newInstance()
//json解析,返回类的实例
return t
}
class Person{
private lateinit var name:String
fun setName(name:String){
this.name = name
}
fun getName():String {
return this.name
}
}
五、泛型约束
1、单层约束
泛型T后追加:具体类名
所传递的类型T必须是JsonObject的子类,或者JsonObject类
fun main() {
val obj:JSONObject ? = fromJson<JSONObject>("json",JSONObject::class.java)
}
fun <T:JSONObject> fromJson(json:String,mClazz:Class<T>):T?{
val t:T? = mClazz.newInstance()
//json解析,返回类的实例
return t
}
2、多重约束
当有多个泛型约束条件是,在方法名后的T后追加where关键字
所传递的类型T必须是JsonObject的子类,或者JsonObject类且实现了Collection<E>接口
fun <T> fromJson(json:String,mClazz:Class<T>):T? where T:JSONObject,T:Collection<T>{
val t:T? = mClazz.newInstance()
//json解析,返回类的实例
return t
}
六、泛型里的out与in
1、out:上限约束
传入的泛型类型可以是T或者T的子类
在Kotlin中,泛型的T不能强制转换,比如父类T的声明和子类E的使用,如果需要强转,需要在T前面加入关键字out,具体代码如下:
fun main(){
//父类转子类,out约束上限
val cat:Group<out Animal> = Group<Cat>()
}
class Group<T>{
}
open class Animal{
}
class Dog: Animal(){
}
class Cat:Animal(){
}
2、in:下限约束
传入的泛型类型可以是T或者T的父类
在Kotlin中,泛型的T不能强制转换,比如父类T的声明和子类E的使用,如果需要强转,需要在子类E前面加入关键字in,具体代码如下:
fun main() {
//子类转父类,in约束下限
val dog:Group<in Dog> = Group<Animal>()
}
class Group<T>{
}
open class Animal{
}
class Dog: Animal(){
}
class Cat:Animal(){
}