Kotlin的泛型比Java更加强大,保障虚拟机运行安全的基础上,功能更加完善。我看了几次泛型都没有记住,回过头来重新梳理总结一番。

定义父类和子类

  1. package william
  2. interface Parent {
  3. }
  4. interface Parent2 {
  5. }
  6. open class Person : Parent, Parent2 {
  7. }
  8. class Child : Person() {
  9. }
  10. class Child2 : Person() {
  11. }

用Java演示

  1. //list1中的元素是Person的子类,但是具体是哪一种不好说。
  2. List<? extends Person> list1 = new ArrayList<>();
  3. //由于不知道具体是Person的哪一个实现类,因此不能往里面添加,只能取出来,起码能确定取出来的一定是Person类型的。
  4. Person number = list1.get(0);
  5. //list2中的元素都是Person的父类。
  6. List<? super Person> list2 = new ArrayList<>();
  7. //由于不知道具体是哪一个父类,因此取出来无法指定具体的引用类型,无法取出来。
  8. //但是却可以往里面添加Person的子类型,因为即使是子类型,也将会在List中被当做Person这个父类型来安全地被操作。
  9. list2.add(new Person());
  10. list2.add(new Child());
  11. /*
  12. 总结:
  13. 一个类用 ? extends T 指定泛型,那么这个泛型只能被输出。(取出来知道是T的子类)
  14. 一个类用 ? super T 指定泛型,那么这个泛型只能被输入。(可以放T的子类进去)
  15. */

用Kotlin演示

用Kotlin完成上面Java做的同样的事情。

  1. val outList: ArrayList<out Person> = ArrayList()
  2. val person: Person = outList.get(0)
  3. val inList: ArrayList<in Person> = ArrayList()
  4. inList.add(Child())
  5. inList.add(Child2())
  6. /*************Java做不到,而Kotlin可以做到的事情********************/
  7. //Person的子类一定更是Parent的子类。用更加抽象的Parent引用,没有任何问题
  8. //输出的类型越来越抽象,安全。
  9. val parentOutList: ArrayList<out Parent> = outList
  10. //Person的父类一定更加是Child的父类。输入更加具体的Child类,没有任何问题
  11. //输入的类型越来越具体,安全。
  12. val childInList: ArrayList<in Child> = inList