Android Kotlin(5)之《接口》

作者: 小强彬 | 来源:发表于2017-07-21 15:32 被阅读176次

    Android Kotlin第五篇 接口。Kotlin系列源码在源码下载这里下载。我们一起来了解下Kotlin的接口,也许我有的地方没有写好,也欢迎大家提出问题,纠正问题。

    1、定义与实现接口

    定义接口
    Kotlin 的接口与 Java 8 类似,既包含抽象方法的声明,也包含实现。与抽象类不同的是,接口无法保存状态。它可以有属性但必须声明为抽象或提供访问器实现。
    关键字 interface 来定义接口,允许方法有默认实现:

    interface inter1{
            fun A() //未实现
            fun B() : String{
                return "已实现"
            }
        }
    

    实现接口
    类或者对象可以实现一个或多个接口。

    class test1 : inter1{
            override fun A() {
                //必须实现
            }
            override fun B():String{
                //非必须实现,因为接口定义方法里有默认实现
    //            return "实现B" //调用test2().B(),返回“实现B”
                return super<inter1>.B() //调用test2().B(),返回“已实现”
            }
        }
    

    2、接口中属性

    接口中的属性只能是抽象的,不允许初始化值,接口不会保存属性值,实现接口时,必须重写属性:

    interface inter2{
            //这里属性是抽象的,不能初始化值
            var stu1 : String
            val stu2 : String
        }
    
        class test2 : inter2{
            //必须初始化抽象属性
            override var stu1: String = "初始刷stu1"
            override val stu2: String = "初始刷stu2"
        }
    

    3、解决覆盖冲突

    实现多个接口时,可能会遇到同一方法继承多个实现的问题。

      interface inter3{
            var a:String
            fun foo():String{
                return a
            } //未实现
            fun A()
            fun B(){}
            fun D() : String{
                return "已实现"
            }
        }
    
        interface inter4{
            var a:String
            var stu:String
            fun foo():String{
                stu+="+inter4"
                return "inter4"
            } //未实现
            fun A()
            fun B()
            fun C():String //有返回类型的接口定义
        }
    

    在上面接口inter3与inter4里,表面上四种冲突(三个伪冲突,一个真冲突):
    -属性a冲突,因为属性是抽象的,在类里实现是唯一的,假冲突,很遗憾目前我也没找到如何在类里区分两个接口下属性方法,如果有大神发现了,告知下哈
    -双默认实现方法foo,真冲突
    -双未实现方法A,假冲突,在类里面是唯一实现方法,同上属性a类型
    -实现方法B与未实现方法B,假冲突,在类里可以解决
    实例:

    class test3 : inter3,inter4{
            override var a : String = "aa"
            override var stu: String=""
            override fun foo() : String{
                return super<inter3>.foo() //输出:aa
            }
    
            fun foo1() : String{
                return super<inter4>.foo() //输出:inter4
            }
    
            fun foo2():String{
                stu = super<inter3>.foo()
                super<inter4>.foo()
                return stu //输出:aa+inter4
            }
    
            override fun A() {
                //inter3与inter4接口里都有A()方法,因为其未实现的方法,所以实际上A方法不存在冲突,只需要实现A方法就行
            }
    
            override fun B() {
                //这里实现的是inter4里面的方法B
            }
            fun B3() {
                super<inter3>.B()//这样你就可以通过B3调用接口inter3里实现的方法B()
            }
    
            override fun C() : String{
                return ""
            }
        }
    

    网友提出的问题

    1、如果多个接口中有命名相同的属性,但属性类型不同,这个时候子类是怎么处理的

    我很开心,我们可以一起商讨和解决一些问题。
    目前我还没有找到方法来区分,但是我们可以用另外两种方法来避免或者处理问题:

    首先,研发严谨性角度我们要尽可能的避免此类问题;
    其次,我们可以像java一样,使用内部类来解决已存在的问题,如下:

        interface inter11{
            var stu1 : Int
        }
        interface inter22{
            var stu1 : String
        }
        //如下这样肯定是不行的,目前还没有找到如何区分属性属于不同接口
        //当然从研发角度看,研发者应该尽可能的避免出现这样情况,如果真的出现了呢怎么办?
        //那么可以学java一样,用内部类继承另外一个接口来实现,如下内部类Class11
    //    inner class class12 : inter11,inter22 {
    //        override var stu1: Int
    //        override var stu1: String
    //    }
        inner class Class11 : inter11 {
            //必须初始化抽象属性
            override var stu1: Int = 1
            private var stu2 = Class22()//调用内部类属性和方法
    
            inner private class Class22 : inter22{
                override var stu1: String = ""
                fun foo() : String{
                    return stu1+this@Class11.stu1 //内部类调用外部属性和方法,this@外部类
                }
            }
            init {
                stu2.stu1 = "初始化"
            }
            fun getStu2(): String{//调用内部类属性
                return stu2.stu1
            }
            fun getFoo() : String{//调用内部类方法
                return stu2.foo()
            }
        }
        fun test4() : String{
    //        return Class11().getStu2() //输出:初始化
            return Class11().getFoo()//输出:初始化1
        }
    

    如果有更好的意见欢迎提出。代码已同步

    这篇很简单,下一篇将会关注Kotlin非常重要的新特性《协程》。到此我们就结束了Kotlin接口的学习,谢谢大家的观赏及支持。

    全套源码下载这里源码会随着后面发布的Kotlin逐渐完善

    相关文章

      网友评论

      • uncochen:我有个疑问,如果多个接口中有命名相同的属性,但属性类型不同,这个时候子类是怎么处理的
        uncochen: @小强彬 期待你的下一篇协程,官方好像说协程部分还不完善
        小强彬:@uncochen 你好!真的很高兴你是第一个提出问题的,我很开心,我们可以一起商讨和解决一些问题。目前我还没有找方法来区分,Kotlin也许后续会逐渐完善,但是我们可以用另外两种方法来避免或者处理问题,首先,研发严谨性角度我们要尽可能的避免此类问题;其次,我们可以像java一样,使用内部类来解决已存在的问题,由于我代码例子写的比较详细,我将我写的已经更新到文章里,如果你有更好的意见欢迎提出,改善我们的代码,一起学习一起进步,加油!

      本文标题:Android Kotlin(5)之《接口》

      本文链接:https://www.haomeiwen.com/subject/imlekxtx.html