【Kotlin】接口

一般接口

Kotlin 中接口和 Java 的接口关键字是一样的,也是通过 interface 来定义一个接口,在 Java 中我定义接口通常如下:

// 接口
interface MyInterface{
    void foo();
}

// 实现类
class MyImpl implement MyInterface{
    @override
    void foo(){
        //TODO
    } 
}

在 Kotlin 中,我们定义接口和 Java 中一样,不过就是因为Kotlin 的方法是有关键字 fun修饰

// 接口
interface MyInterface{
    fun foo()
}

// 实现类
class MyImpl:MyInterface{
   override fun foo(){
       //TODO
   }
}

这里看上去和 Java 几乎是一模一样,而在 Java8 之后支持接口里面的默认方法例如

// 接口
interface MuInterface{
    void foo();
    default void bar(){
        // TODO 
    }
}

// 实现类
class MyImpl implement MyInterface{
    @override
    void foo(){
        //TODO
    } 
}

kotlin 如此先进的语言肯定也是支持默认方法的,甚至更胜一筹

// 接口
interface MyInterface{
    fun foo()
  
    fun bar(){
        //TODO
    }
}
// 实现类
class MyImpl:MyInterface{
   override fun foo(){
       //TODO
   }
}

我们将 两段kotlin 的代码反编译为 Java 代码看下:

// 没有默认方法的接口
public interface MyInterface {
   void foo();
}


// 有默认方法的接口
public interface MyInterface {
   void foo();

   void bar();

   public static final class DefaultImpls {
      public static void bar(@NotNull MyInterface1 $this) {
         // TODO
      }
   }
}

通过反编译的代码我们看到,其实默认方法的是通过在接口内部创建了一个静态内部类来实现的DefaultImpls,如果调用接口默认的方法,则会调用到内部类的静态方法。这也就解释了为什么在低版本的 jdk 上也可以使用默认方法了。(起初 kotlin 的 jdk 版本为1.6)

接口继承

接口的继承和类的继承一样,使用: 表示继承关系,示例:

interface MyInterface1 {
    fun foo()
}

interface MyInterface2:MyInterface1{
    fun bar()
}

多继承问题

我们学习 Java 接口的时候经常会使用鸟类来举例子,那么这里我们也是用这个来举例:我们假设有两个接口AnimalFlyer,Bird

定义如下:

interface Flyer{
    fun fly()
    fun eat()
}

interface Animal {
    fun eat()
}

class Bird:Flyer,Animal{
    override fun fly() {
        println("i can fly")
    }

    override fun eat() {
        println("i can eat")
    }
}

这里还比较常见,可以通过复写 eat 方法即可,我们再看下面这个例子

public interface InterfaceA {
    default void foo(){
        System.out.println("foo");
    }

    void bar();
}

public interface InterfaceB {
    default void foo(){
        System.out.println("foo");
    }

    default void bar(){
        System.out.println("bar");
    }
}

public class MyImplB implements InterfaceA,InterfaceB{
    @Override
    public void foo() {
        InterfaceA.super.foo();
        InterfaceB.super.foo();
    }

    @Override
    public void bar() {
        InterfaceB.super.bar();
    }
}

这里因为有默认方法,而且两个接口方法名称还是一样的,实现的时候我们实现类中通过**接口名.super.方法名,实现 super,那么这个在 kotlin 中怎么实现呢,kotlin 可以通过super<接口名>.方法名**,做到指定方法实现,代码如下

interface A {
    fun foo() { print("A") }
    fun bar()
}

interface B {
    fun foo() { print("B") }
    fun bar() { print("bar") }
}

class C : A {
    override fun bar() { print("bar") }
}

class D : A, B {
    override fun foo() {
        super<A>.foo()
        super<B>.foo()
    }

    override fun bar() {
        super<B>.bar()
    }
}

函数式接口/SAM接口

只有一个抽象方法的接口就是 函数式接口,这个在 Android 中很常见,比如各种监听。而这类函数式接口,可以在 interface 之前,添加一个 fun,表示这是一个函数式接口

fun interface MyInterface{
    fun foo()
}

这样做有什么好处呢?我们之前在学习 object 的时候提到过,如果方法只有一个,是可以通过 lambda 表示来减少代码,使代码简洁明了。

例如通常我们这么定义的接口和实现

interface A {
    fun foo()
}

fun main() {
    val a: A = object : A {
        override fun foo() {
            TODO("Not yet implemented")
        }
    }
}

因为 A 接口中只有一个方法,所以我们通过函数式接口来做的话就是

fun interface A {
    fun foo()
}

fun main() {
    val a: A = A { TODO() }
}

这里很像我们之前写click 监听写了一大串 new xxlistener,然后里面 override xx 方法,通过 Java8 的 lambda 表达式只需要new xxlistener(()->{ xxx})这样简单明了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
回答: 在Kotlin中,可以使用lambda表达式来简化接口回调的实现。通过lambda表达式,可以直接将函数作为参数传递给其他函数或方法。这样可以避免创建额外的接口和实现类。例如,可以使用lambda表达式来简化setOnItemClickListener的实现。在SomeListAdapter类中,可以直接定义一个函数类型的变量mOnItemClickListener,并将其作为参数传递给onBindViewHolder方法。这样就可以在onBindViewHolder方法中直接调用mOnItemClickListener函数,而不需要使用setOnItemClickListener方法。\[1\] 另外,如果想要在Kotlin中实现接口回调,可以使用接口类型变量和lambda表达式的组合。可以定义一个接口类型变量mListener,并使用setListener方法将lambda表达式作为参数传递给mListener。然后在work方法中,可以直接调用mListener的方法。这样就可以实现接口回调的功能。\[2\] 此外,如果想要在Kotlin中实现点击事件的回调,可以使用匿名内部类的方式。可以通过setOnClickListener方法,传入一个匿名内部类对象,并在该对象中重写onClick方法。在onClick方法中,可以实现点击事件的逻辑。\[3\] #### 引用[.reference_title] - *1* [kotlin接口回调](https://blog.csdn.net/weixin_33716941/article/details/91874861)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [Kotlin 高级函数实现回调详解](https://blog.csdn.net/weixin_42046829/article/details/105763041)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

0neXiao

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值