kotlin多态
1.概念
相同类型对象调用同一个方法或属性时可能呈现出多种不同子类(子类重写了该方法或属性的话)行为或特征。(或者说编译时状态是父类类型,运行时状态可能是其他多种子类类型)。
向上转型:子类实例(或说对象)赋给父类变量(或说引用)时。
向下转型:父类类型实例赋给子类类型变量时。
2.强制转换(向下转型)
(1)is和!is运算符
-
用于判断is前面变量是否是后面类的一个实例,前面变量在编译期时要与后面类的类型相同或者是父子关系,否则编译不通过。
fun main(args: Array<String>) { val a : Any = "测试多态" println("a is Date类型:${a is Date}")//false 编译期可以通过,因为编译期a是Any类型,而Date也继承于Any,但运行时a显然不是Date类型 val b : String = "测试多肽" // println("b is Date类型:${b is Date}")//编译不能通过,编译期b是String类型 }
-
is、!is智能转换
fun main(args: Array<String>) { val a : Any = "测试is向下转型" // println(a.length)//编译不通过,Any没有length属性 if (a is String) println(a.length)//通过is判断 if (a !is String) return//通过!is也可以判断 println(a.length) }
(2)as和as?运算符强制类型转换
强制类型转换只能在有父子关系之间进行,否则会抛出类型转换异常(ClassCastException)。
-
as
不安全转换,转换失败抛ClassCastException。
fun main(args: Array<String>) { val any : Any = "测试as向下转型" val str : String = any as String//编译通过,因为any是Any类型,String是Any子类,运行也没问题,因为any运行时也是String类型 val any2 : Any = 2 var str2 : String = any2 as String//编译通过,因为any2是Any类型,String是Any子类,运行抛类型转换异常 }
-
as?
安全转换,转换失败返回null,注意返回类型也是一个安全类型String?而不是String
fun main(args: Array<String>) { val any : Any = "测试as?向下转型" val str : String? = any as? String//编译通过,因为any2是Any类型,String是Any子类,运行也没问题,因为any2运行时也是String类型 val any2 : Any = 2 val str2 : String? = any2 as? String//编译通过,因为any2是Any类型,String是Any子类,使用as?安全转换,返回null println(str2?.length)//String?类型,安全调用 }