课程名称:移动端架构师
课程章节:Android必备Kotlin核心技术
课程讲师:CrazyCodeBoy LovelyChubby
课程内容:
泛型接口/类(泛型类型)
泛型字段
泛型方法
泛型约束
泛型中的out与in
定义泛型类型,是在类型名之后、主构造函数之前用尖括号括起的大写字母类型参数指定:
Java:
//泛型接口 interface Fruit<T> { T taste(); void price(T t); }
Kotlin:
//泛型接口 interface Fruit<T> { fun taste(); T void price(t: T) }
Java
abstract class Color<T> { T t; abstract void printColor(); } class Blue { String color = "blue"; } class BlueColor extends Color<Blue> { public BlueColor(Blue t) { this.t = t; } @Override public void printColor() { System.out.println("color:" + t.color); } }
Kotlin
abstract class Color<T>(var t: T/*泛型字段*/) { abstract fun printColor() } class Blue { val color = "blue" } class BlueColor(t: Blue) : Color<Blue>(t) { override fun printColor() { println("color:${t.color}") } }
定义泛型类型字段,可以完整地写明类型参数,如果编译器可以自动推定类型参数,也可以省略类型参数:
abstract class Color<T>(var t: T/*泛型字段*/) { abstract fun printColor() }
Kotlin 泛型方法的声明与 Java 相同,类型参数要放在方法名的前面:
Java
public static <T> T fromJson(String json, Class<T> tClass) { T t = null; try { t = tClass.newInstance(); } catch (Exception e) { e.printStackTrace(); } return t; }
Kotlin
fun <T> fromJson(json: String, tClass: Class<T>): T? { /*获取T的实例*/ val t: T? = tClass.newInstance() return t }
Java 中可以通过有界类型参数来限制参数类型的边界,Kotlin中泛型约束也可以限制参数类型的上界:
Java
public static <T extends Comparable<? super T>> void sort(List<T> list){}
Kotlin
fun <T : Comparable<T>?> sort(list: List<T>?){}
sort(listOf(1, 2, 3)) // OK,Int 是 Comparable<Int> 的子类型 // sort(listOf(Blue())) // 错误:Blue 不是 Comparable<Blue> 的子类型
对于多个上界的情况
//多个上界的情况 fun <T> test(list: List<T>, threshold: T): List<T> where T : CharSequence, T : Comparable<T> { return list.filter { it > threshold }.map { it } }
所传递的类型T必须同时满足 where 子句的所有条件,在上述示例中,类型 T 必须既实现了 CharSequence 也实现了 Comparable。
在Kotlin中out代表协变,in代表逆变,为了加深理解我们可以将Kotlin的协变看成Java的上界通配符,将逆变看成Java的下界通配符:
//Kotlin使用处协变 fun sumOfList(list: List<out Number>) //Java上界通配符 void sumOfList(List<? extends Number> list) //Kotlin使用处逆变 fun addNumbers(list: List<in Int>) //Java下界通配符 void addNumbers(List<? super Integer> list)
Java 泛型 | Java 中代码示例 | Kotlin 中代码示例 | Kotlin 泛型 |
---|---|---|---|
泛型类型 | class Box<T> | class Box<T> | 泛型类型 |
泛型方法 | <T> T fromJson(String json, Class<T> tClass) | fun <T> fromJson(json: String, tClass: Class<T>): T? | 泛型函数 |
有界类型参数 | class Box<T extends Comparable<T> | class Box<T : Comparable<T>> | 泛型约束 |
上界通配符 | void sumOfList(List<? extends Number> list) | fun sumOfList(list: List<out Number>) | 使用处协变 |
下界通配符 | void addNumbers(List<? super Integer> list) | fun addNumbers(list: List<in Int>) | 使用处逆变 |
总的来说,Kotlin 泛型更加简洁安全,但是和 Java 一样都是有类型擦除的,都属于编译时泛型。
KotlinGeneric.kt
package com.demon.kotlin fun main() { println(Coke().taste().price) testSort() } /** * Generic 泛型 * 泛型接口 */ interface Drinks<T> { fun taste(): T fun price(t: T) } class Sweet { val price = 5 } class Coke: Drinks<Sweet> { override fun taste(): Sweet { println("Sweet") return Sweet() } override fun price(t: Sweet) { println("Coke price: ${t.price}") } } /** * 泛型类 * BlueColor(Blue()).printColor() */ abstract class Color<T>(var t: T /*泛型字段*/) { abstract fun printColor() } class Blue { val color = "blue" } class BlueColor(t: Blue): Color<Blue>(t) { override fun printColor() { println("color:${t.color}") } } /** * 泛型方法 */ fun <T> fromJson(josn: String, tClass: Class<T>): T? { //获取T的实例 val t: T? = tClass.newInstance() return t; } /** * 泛型约束 * :表示上界,T extends Comparable<T>? */ fun <T: Comparable<T>?> sort(list: List<T>?){} fun testSort() { sort(listOf(1, 2, 3, 4)) //OK, Int 是Comparable<Int>的子类型 // sort(listOf(Blue())) // 错误,Blue不是Comparable<Blue>的子类型 val listString = listOf("A", "B", "C") val list = testa(listString, "B") println(list) } /** * 多个上界的情况 * 所传递的类型T必须同时满足 where 子句的所有条件,在上述示例中,类型 T 必须既实现了 CharSequence 也实现了 Comparable。 */ fun <T> testa(list: List<T>, threshold: T): List<T> where T : CharSequence, T : Comparable<T> { return list.filter { it > threshold }.map { it } } /** * 泛型中的out与in */ // Kotlin使用处协变 = Java上界通配符: void sumOfList(List<? extends Number> list) fun sumOfList(list: List<out Number>) {} //Kotlin使用处逆变 = Java下界通配符: void addNumbers(List<? super Integer> list) //fun addNumbers(list: List<in Int>) {}
课程收获:
谢谢老师,这一章学习kotlin泛型的使用,期待后边的继续学习。