Kotlin学习(七)——接口

之前在类的继承中,我们已经提到了接口,本片博客我们来详细讲讲接口
首先要重点说一下:Kotlin中的Lambda表达式和Java中的Lambda表达式有点不一样
Kotlin中lambda表达式是,实现一个函数,而Java中是实现函数式接口
Kotlin中函数可以当做函数的参数:

fun getArraySum(array: Array<Int>,add:(a:Int,b:Int) -> Int):Int{ //add 就是一个参数为(a:Int,b:Int)返回值为Int型的函数
    var sum = 0
    for (item in array){
        sum = add(sum,item)
    }
    return sum
}

fun main(args: Array<String>) {
    var array = arrayOf(1,2,3,4,5,6)
    var sum = getArraySum(array){ a,b -> a+b } //用lambda表达式实现函数
}

而在Java里:
首先我们要有函数式接口:

//这就是一个函数是的接口
public interface Add {
     int add(int a,int b);
}

然后我们才能使用lambda表达式实现函数式接口:

public class LambdaTest {
    public static void main(String[] args) {
        //实现Add函数式接口
        Add a = (x,y) -> x + y; //返回的是接口类型
        int add = a.add(1,3);
        System.out.println(add);

    }
}

根据以上的分别,我们要注意以下几点
1. Kotlin中并没有函数式接口,lambda表达式只能实现函数声明
2. Kotlin要实现函数式接口,也只能实现Java的函数式接口
3. Kotlin和Java相比较,还是Kotlin简单,因为Kotlin实现函数声明返回的是声明的类型,直接用这个类型的引用调用方法就好。而Java还要通过接口类型的实现类的对象的引用来调用实现的方法(表达起来都拗口)
4. 但是两者相同点是:两个实现的最终目标是函数或者接口

题外话说了很久,我们来说这篇博客的主题:接口

接口的声明和实现

Kotlin 的接⼝与 Java 8 类似,既包含抽象⽅法的声明,也包含实现。与抽象类不同的是,接⼝⽆法保存状态。它可以有属性但必须声明为抽象或提供访问器实现

get一下上面的信息点:
1. Kotlin接口中属性要么是抽象的,要么提供访问器实现
2. Kotlin接口中方法要么是抽象的,要么实现它(有方法体)
3. 抽象类能保存状态,接口不能保存状态

接口的声明
使⽤关键字 interface 来定义接⼝:

interface MyInterface {
    fun bar()
    fun foo() {
        // 可选的⽅法体,这里能有方法体里面的代码
    }
}

实现接⼝:
⼀个类或者对象可以实现⼀个或多个接⼝。

class Child : MyInterface {
    override fun bar() {
        // ⽅法体
    }
}

接口里的属性

你可以在接⼝中定义属性。在接⼝中声明的属性要么是抽象的,要么提供访问器的实现。在接⼝中声明的属性不能有幕后字段(backing field),因此接⼝中声明的访问器不能引⽤它们
再次get一下上面的意思:
1,接口中的属性要么是抽象的,一定会被覆盖,要么就是提供访问器的
2. 接口中属性没有幕后字段,所以不可能只实现一个访问器,默认一个。要么两个都实现,要么属性是val类型的,实现其getter

interface A{
    val bb :String   //因为幕后字段不能用,所以一般情况下要实现访问器的只有val类型的属性
        get() = "lal"
    var aa : Int
}

class AA :A {
    override var aa: Int = 9

}

解决覆盖冲突

实现多个接⼝时,可能会遇到同⼀⽅法继承多个实现的问题。例如

//声明两个接口
interface A {
    fun foo() { print("A") } //和接口B中的foo函数同名
    fun bar()
}
interface B { 
    fun foo() { print("B") } //和接口A中的foo函数同名
    fun bar() { print("bar") }
}
class C : A { //类C只实现了一个接口,不要解决冲突
    override fun bar() { print("bar") } 
} 
class D : A, B { //类D实现了两个接口,要符合覆盖规则,所以要解决冲突
    override fun foo() { //为了不冲突,提供自己的实现
        super<A>.foo()
        super<B>.foo()
    } 
    override fun bar() {//为了不冲突,提供自己的实现
        super<B>.bar()
    }
}

下面再帖一下官方的说明:
上例中,接⼝ A 和 B 都定义了⽅法 foo() 和 bar()。两者都实现了 foo(), 但是只有 B 实现了 bar() (bar() 在 A 中没有标记为抽象,因为没有⽅法体时默认为抽象)。因为 C 是⼀个实现了 A 的具体类,所以必须要重写 bar() 并实现这个抽象⽅法。
然⽽,如果我们从 A 和 B 派⽣ D,我们需要实现我们从多个接⼝继承的所有⽅法,并指明 D 应该如何实现它们。这⼀规则既适⽤于继承单个实现(bar())的⽅法也适⽤于继承多个实现(foo())的⽅法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值