Kotlin中的接口

作者: 程序员丶星霖 | 来源:发表于2019-11-20 09:10 被阅读0次

    一、接口的定义

    接口定义的基本语法:

    [修饰符] interface 接口名 : 父接口1,父接口2...{
        0~N个属性定义...
        0~N个方法定义...
        0~N个嵌套类、嵌套接口、嵌套枚举定义...
    }
    
    • 修饰符可以是public | internal | private中的任意一个,或完全省略修饰符。如果省略了访问控制符,则默认采用public。
    • 接口名应与类名采用相同的命名规则。接口名通常使用形容词。
    • 一个接口可以有多个直接父接口,但接口只能继承接口,不能继承类。

    接口定义的是一种规范,因此接口中不能包含构造器和初始化块定义。

    Kotlin接口与Java接口的区别:

    • Java接口中的所有成员都会自动使用public修饰,如果为这些成员指定访问权限,也只能指定public访问权限;
    • Kotlin接口中的成员可支持private和public两种访问权限。
    interface Outputable {
        //只读属性定义了getter方法,非抽象属性
        val name: String
            get() = "输出设备"
        //只读属性没有定义getter方法,抽象属性
        val brand: String
        //读写属性没有定义getter、setter方法,抽象属性
        var category: String
    
        //接口中定义的抽象方法
        fun out()
    
        fun getDate(msg: String)
    
        //接口中定义的非抽象方法,可使用private修饰
        fun print(vararg msgs: String) {
            for (msg in msgs) {
                println(msg)
            }
        }
    
        fun test() {
            println("接口中的test()方法")
        }
    }
    

    二、接口的继承

    接口的继承和类的继承不一样,接口支持多继承,即一个接口可以有多个直接父接口。

    interface InterfaceA {
        val propA: Int
            get() = 5
    
        fun testA()
    }
    
    interface InterfaceB {
        val propB: Int
            get() = 6
    
        fun testB()
    }
    
    interface InterfaceC : InterfaceA, InterfaceB {
        val propC: Int
            get() = 7
    
        fun testC()
    }
    

    三、使用接口

    接口不能用于创建实例,但可以用于声明变量。接口的主要用途就是被实现类实现。

    接口的主要用途:

    • 定义变量,也可用于进行强制类型转换。
    • 被其他类实现。

    实现接口可以获得所实现接口中定义的属性、方法。

    package `0704`
    
    interface Product {
        fun getProduceTime(): Int
    }
    
    const val MAX_CACHE_LINE = 10
    
    class Printer : Outputable, Product {
        private val printData = Array<String>(MAX_CACHE_LINE, { "" })
        //用以记录当前需打印的作业数
        private var dataNum = 0
        //重写接口的抽象只读属性
        override val brand: String = "HP"
        //重写接口的抽象读写属性
        override var category: String = "输出外设"
    
        override fun out() {
            //只要还有作业,就继续打印
            while (dataNum > 0) {
                println("打印机打印:" + printData[0])
                //把作业队列整体前移一位,并将剩下的作业数减1
                System.arraycopy(printData, 1, printData, 0, --dataNum)
            }
        }
    
        override fun getDate(msg: String) {
            if (dataNum >= MAX_CACHE_LINE) {
                println("输出队列已满,添加失败")
            } else {
                //把打印数据添加到队列里,已保存数据的数量加1
                printData[dataNum++] = msg
            }
        }
    
        override fun getProduceTime(): Int {
            return 45
        }
    }
    
    fun main(args: Array<String>) {
        //创建一个Printer对象,当成Output使用
        var o: Outputable = Printer()
        o.getDate("Kotlin入门")
        o.getDate("Kotlin进阶")
        o.out()
        o.getDate("Kotlin高级")
        o.getDate("Kotlin实战")
        o.out()
        //调用Outputable接口中定义的非抽象方法
        o.print("刘备", "关羽", "张飞")
        o.test()
        //创建一个Printer对象,当成Product使用
        val p:Product=Printer()
        println(p.getProduceTime())
    }
    

    输出结果:

    打印机打印:Kotlin入门
    打印机打印:Kotlin进阶
    打印机打印:Kotlin高级
    打印机打印:Kotlin实战
    刘备
    关羽
    张飞
    接口中的test()方法
    45
    

    接口不能显式继承任何类,但所有接口类型的变量都可以直接赋给Any类型的变量。

    四、接口和抽象类

    接口和抽象类的相似之处如下:

    • 都不能被实例化,都位于继承树的顶端,用于被其他类实现和继承。
    • 都可以包含抽象成员,实现接口或继承抽象类的普通子类都必须实现这些抽象成员。

    接口和抽象类的差别:

    • 接口作为系统与外界交互的窗口,体现的是一种规范。当在一个程序中使用接口时,接口是多模块之间的耦合标准;当在多个应用程序之间使用接口时,接口时多个程序之间的通信标准。
    • 抽象类作为系统中多个子类的共同父类,所体现的是一种模板模式设计。
    • 接口中不包含构造器;但抽象类中可以包含构造器,抽象类中的构造器并不是用于创建对象的,而是让其子类调用这些构造器来完成属于抽象类的初始化操作。
    • 接口中不能包含初始化块;但抽象类中则完全可以包含初始化块。
    • 一个类最多只能有一个直接父类,包括抽象类;但一个类可以直接实现多个接口,通过实现多个接口可以弥补Kotlin单继承的不足。

    学海无涯苦作舟

    我的微信公众号.jpg

    相关文章

      网友评论

        本文标题:Kotlin中的接口

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