能否用Kotlin的by关键字通过同一委托实现两个接口?
解决方案
你可以通过以下几种方式,既不用暴露构造函数参数,也不会创建多个C实例,完美实现用同一个委托对象实现两个接口:
方式1:私有构造函数+默认无参构造
这种方式对外保持无参构造,内部创建专属的C实例:
interface A { fun foo() } interface B { fun bar() } class C : A, B { override fun foo() { println("执行C的foo方法") } override fun bar() { println("执行C的bar方法") } } class D private constructor(private val c: C) : A by c, B by c { // 对外提供无参构造,内部自动创建C实例 constructor() : this(C()) }
外部调用D()时,会自动创建一个专属的C实例,所有接口方法都委托给这个实例,不会产生多个C对象。
方式2:懒加载共享实例(单例式)
如果希望所有D实例共享同一个C对象,可以用伴生对象+懒加载:
class D : A by sharedC, B by sharedC { companion object { private val sharedC by lazy { C() } } }
这种方式下,sharedC只会被初始化一次,所有D的实例都会复用这个C对象,适合单场景的复用需求。
方式3:类内懒加载实例(每个D对应一个C)
如果要每个D实例拥有自己的C对象,同时不想修改构造函数,可以用类内的懒加载属性:
class D : A by c.value, B by c.value { private val c = lazy { C() } }
lazy会确保第一次访问时才创建C实例,两个接口的委托都会指向这个唯一的实例。
无需编写样板代码
完全不用手动实现A和B的所有方法,上述几种方式都是利用Kotlin委托特性的标准写法,简洁高效,避免了样板代码的冗余。
内容的提问来源于stack exchange,提问作者Malachi Holden
相关产品推荐
相关产品推荐

