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?类型,安全调用
    }
    
posted @ 2019-05-24 19:43  谢光伟  阅读(787)  评论(0编辑  收藏  举报