How to provide interface implementation using two combined classes?

Viewed 86

I have the following interface and two classes:

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

class B {
    fun foo() {}
}

class C {
    fun bar() {}
}

Is it possible to somehow provide implementation for this interface using/combining those 2 classes?

2 Answers

One way to do this without changing the given code is to just use instances of B and C in a new class implementing A:

class D : A {
    private val b = B()
    private val c = C()
    
    override fun foo() = b.foo()
    override fun bar() = c.bar()
}

This doesn't scale very well though, and requires to write boilerplate. With Kotlin you can implement interfaces by delegation, which basically does exactly the above, but automatically. However, this requires you to split your interface A into the part that is implemented by B and the part implemented by C:

interface Foo {
    fun foo()
}
interface Bar {
    fun bar()
}
interface A : Foo, Bar

class B : Foo {
    override fun foo() {}
}

class C : Bar {
    override fun bar() {}
}

class D : A, Foo by B(), Bar by C()

If you need configurable instances of B and C, you can pass them to D via its constructor:

class D(val b: B, val c: C): A, Foo by b, Bar by c

If B and/or C have constructors that take arguments, you can create instances of B and/or C using parameters from D's constructor:

class B(val something: String) : Foo { ... }

class D(something: String) : A, Foo by B(something), Bar by C()

You can create a new class that implements this interface and delegate method invocation to these classes.

class D(val b: B, val c: C) : A {

    override fun foo() {
        return b.foo()
    }

    override fun bar() {
        return c.bar()
    }
}

Or if you have access to interface A, you can change it next way

interface AB {
    fun foo()
}

interface AC {
    fun bar()
}

interface A : AB, AC

class B : AB {
    override fun foo() {}
}

class C : AC {
    override fun bar() {}
}

class D(val b: B, val c: C) : AB by b, AC by c, A

So, now, your D class implements interface A using delegates

Related