Kotlin 函数接口与普通接口的区别

记一次编写Demo时SonarLint提示警告而关注到的kotlin1.4新增的接口声明方式.

// SonarLint警告: Make this interface functional or replace it with a function type.
interface GitHubService {  
  
    @GET("search/repositories?sort=stars&q=Android")  
    suspend fun searchRepos(@Query("page") page: Int, @Query("per_page") perPage: Int): GitHubResponse  
  
}


// 声明为函数接口后修复警告
fun interface GitHubService {  
  
    @GET("search/repositories?sort=stars&q=Android")  
    suspend fun searchRepos(@Query("page") page: Int, @Query("per_page") perPage: Int): GitHubResponse  
  
}

普通接口

当使用 interface 关键字定义接口时,可以声明抽象方法和默认方法。抽象方法是没有具体实现的方法,需要在实现接口的类中提供具体的实现。默认方法是在接口中提供了一个默认的实现,实现类可以选择重写或者直接使用默认实现。

interface GitHubService {
    fun getUser(username: String): User  // 抽象方法

    fun getRepositories(username: String): List<Repository> {  // 默认方法
        val user = getUser(username)
        // 通过用户获取仓库列表的具体实现
        // ...
        return repositories
    }
}

函数接口

使用 fun interface 声明的接口只能包含一个抽象方法,并且不能包含默认方法。这种类型的接口通常用于函数式编程和 lambda 表达式的场景。实现这个接口的类可以通过 lambda 表达式或者函数引用来提供方法的具体实现。

fun interface GitHubService {
    fun getUser(username: String): User
}

// 通过 lambda 表达式为 getUser 方法提供了具体的实现。
// lambda 表达式接收一个用户名参数,并返回对应的用户对象。
val service = GitHubService { username -> 
    // 通过用户名获取用户的具体实现
    // ...
    return user
}

常见使用场景

interface
  1. 定义回调接口:接口可以用作定义回调函数的契约。一个类可以实现接口并提供回调方法的具体实现,然后将实现类的实例传递给其他需要回调的组件。

  2. 实现多态行为:接口可以作为多态的手段,使得不同的类可以以不同的方式实现相同的接口。这种多态的特性允许在运行时根据对象的具体类型调用相应的方法。

  3. 定义服务接口:接口可以定义服务契约,描述系统的服务功能,并规定服务方法的签名。其他模块或组件可以实现接口,并提供具体的服务实现。

  4. 定义插件机制:接口可以用于定义插件的扩展点。主应用程序定义接口,并提供默认实现,而插件可以实现这个接口并提供自定义的行为。

  5. 实现策略模式:接口可以用于实现策略模式,其中不同的类实现相同的接口,并提供不同的算法或策略。

fun interface
  1. 定义函数式接口:函数式接口只包含一个抽象方法,通常用于表示某个操作或行为。这样的接口可以作为函数类型的参数或返回值,使得函数可以被传递、组合和使用。

  2. 使用 lambda 表达式:函数式接口可以通过 lambda 表达式提供方法的具体实现。这种方式使得代码更加简洁、易读,并支持函数式编程的风格。

  3. 支持函数引用:函数式接口可以与函数引用一起使用,允许直接引用已有的函数作为接口的实现。这样可以减少冗余的代码,并提高代码的可读性。

总而言之,interface 关键字适用于一般的接口定义和多态行为,而 fun interface 关键字则适用于函数式编程和 lambda 表达式的场景。 总结一下,interface 关键字用于定义常规的接口,可以包含抽象方法和默认方法。而 fun interface 关键字用于定义函数式接口,只能包含一个抽象方法,并且不能包含默认方法。

全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务