Kotlin中如何简洁实现含匿名接口实例属性的MathOperator接口?
解决Kotlin中函数式接口实例化的错误
你遇到的“Property getter or setter expected”错误,核心原因是Kotlin默认不会把普通接口视为函数式接口——即使它只有一个抽象方法。Java允许直接用lambda实现单抽象方法接口,但Kotlin需要显式标记这类接口为函数式接口才能支持同样的写法。
简洁的解决方案:使用fun interface
从Kotlin 1.4开始,我们可以用fun interface关键字声明函数式接口,这样就能像Java一样用lambda快速实例化接口对象了。修改后的代码如下:
import java.util.Deque fun interface KTMathOperator { fun evaluate(stack: Deque<Float>): Float companion object { val ADD = KTMathOperator { stack -> stack.pop() + stack.pop() } val SUB = KTMathOperator { stack -> -stack.pop() + stack.pop() } val MUL = KTMathOperator { stack -> stack.pop() * stack.pop() } } }
为什么这样可行?
fun interface告诉Kotlin编译器:这个接口只有一个抽象方法,可以用lambda表达式来简化实例化。编译器会自动把lambda映射到接口的evaluate方法上,和Java的行为完全一致,代码也保持了简洁性。
兼容旧版本Kotlin的替代方案
如果你的项目使用Kotlin 1.4之前的版本,无法使用fun interface,可以用匿名内部类的方式实现,虽然代码稍长,但逻辑是一致的:
import java.util.Deque interface KTMathOperator { fun evaluate(stack: Deque<Float>): Float companion object { val ADD = object : KTMathOperator { override fun evaluate(stack: Deque<Float>): Float { return stack.pop() + stack.pop() } } val SUB = object : KTMathOperator { override fun evaluate(stack: Deque<Float>): Float { return -stack.pop() + stack.pop() } } val MUL = object : KTMathOperator { override fun evaluate(stack: Deque<Float>): Float { return stack.pop() * stack.pop() } } } }
使用示例
不管哪种实现方式,调用逻辑都和Java一致:
import java.util.ArrayDeque fun main() { val stack = ArrayDeque<Float>().apply { push(2f) push(3f) } println(KTMathOperator.ADD.evaluate(stack)) // 输出5.0 }
内容的提问来源于stack exchange,提问作者warownia1
相关产品推荐
相关产品推荐

