1.官方文档
英文:https://kotlinlang.org/docs/reference/generics.html
中文:https://www.kotlincn.net/docs/reference/generics.html
2.类模板
2.1 简单类模板
1 //类模板 2 fun test_template1() { 3 4 class Student(val n : String) { override fun toString(): String { return "student.name = $n" } } 5 6 //简单类模板 7 open class A <T> (var t : T ) { override fun toString(): String { return "t = $t" } } 8 9 A(1).let { Log.e(TAG_TEMPLATE,"A <Int> : $it") } 10 11 A("string template").let { Log.e(TAG_TEMPLATE,"A <String> : $it") } 12 13 A<Float>(1314.0f).let { Log.e(TAG_TEMPLATE,"A <Float> : $it") } 14 15 A(Student("li3")).let { Log.e(TAG_TEMPLATE,"A <Student> : $it") } 16 17 }
结果
A <Int> : t = 1
A <String> : t = string template
A <Float> : t = 1314.0
A <Student> : t = student.name = li3
2.2 模板与继承
1 interface TIF <T> 2 interface TIF2 <E> : TIF <Int> //接口模板继承某个特定类型 3 interface TIF3 <U> : TIF <U> //接口模板继承接口模板 4 5 fun test_template2(){ 6 7 8 class A : TIF<Int> //实现接口模板 9 10 open class B <T> () 11 class C : B<Int>() //普通类继承类模板 12 class D<N> : B<N>() //类模板继承类模板 13 14 15 open class E <T,U> //多个参数类模板 16 class F : E <Int,Float>() 17 class G <T> : E <T,Int>() 18 19 }
3.函数模板
3.1 简单函数模板
1 //1.简单函数模板 2 class Student(val name : String = ""){ override fun toString(): String { return "name = $name" } } 3 4 fun <T> fun1( t : T ) { 5 Log.e(TAG_TEMPLATE,"test_template3 t : $t") 6 } 7 8 fun1(1) 9 fun1(1.0f) 10 fun1(Student("li3 "))
结果
test_template3 t : 1
test_template3 t : 1.0
test_template3 t : name = li3
3.2 不支持默认实参
fun <T> fun2( t : T = Int ) { } //不支持默认实参
3.3 能返回类模板
1 //3.函数参数、返回值 用类模板 2 class A <T> (var t : T ) { override fun toString(): String { return "t = $t" } } 3 fun <T> fun3(t : T) : A <T>{ 4 return A(t) 5 } 6 fun3(1).let { Log.e(TAG_TEMPLATE,"test_template3 it: $it") }
结果
test_template3 it: t = 1
4.模板类型的型变
4.1 java中模板的型变
java中,模板参数的子类型与它的基类型是两个类型,不能把子类型当作基类型,具体如下:
- 已知 List是个接口模板,它的声明如下 public interface List<E> extends Collection<E>
- 已知 Object是String的基类。
1 public ArrayList list = new ArrayList<String>(); 2 public ArrayList objects= new ArrayList<Object>();