Happy to create a formal proposal, and it’s totall...
# language-proposals
e
Happy to create a formal proposal, and it’s totally possible I’m overlooking something, but I’d like to check if partial interface implementation delegates is something that’s achievable. Here’s a sample:
Copy code
// delegation as of now:

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

class AImpl() : A { override fun foo() = println("default foo") }
class BImpl(private val a: AImpl) : B, A by a { override fun bar() = println("bar") }

// delegation after proposal:
interface A { fun foo() }
interface B : A { fun bar() }

class AImpl() : A { override fun foo() = println("default foo") }
class BImpl(private val a: AImpl) : B by a { override fun bar() = println("bar") }
Hope this makes sense. The benefit is that
BImpl
does not have to explicitly rely on interface
A
.
u
Can't you just go with the following delegation?
Copy code
class BImpl(private val a: A) : A by a, B { override fun bar() = println("bar") }
e
@uli if possible, I would avoid direct usage of
A
at
BImpl
.
u
So what is the motivation for avoiding A? Especially where kotlin has a policy of being explicit and you want to delegate A's method?
e
“test the interface, not the implementation”. With the current delegation approach, I need to test
BImpl
rather than
B
.
(I know, it would be covered by testing
A
via
AImpl
)
also
Copy code
// this works
interface A { fun foo() }
interface B { fun bar() }

class Mixed : A, B {
   override fun foo() {}
   override fun bar() {}
}

// this works as well
interface A { fun foo() }
interface B : A { fun bar() }

class Mixed : B {
   override fun foo() {}
   override fun bar() {}
}

// this also works
interface A { fun foo() }
interface B { fun bar() }

class Mixed(val a: AImpl) : B, A by a {
   override fun bar() {}
}

// now I don't see a reason why this should not work
interface A { fun foo() }
interface B : A { fun bar() }

class Mixed(val a: AImpl) : B by a {
   override fun bar() {} // I still need to implement methods defined in interface B
}
u
How would mentioning A in your declaration change your tests? The result should actually be identical to what the compiler would do. Why would you start testing BImpl instead of B?
You would test B which includes
fun foo(), inherited from A
e
actually there is a workaround which I don’t really like but works in this case:
Copy code
interface A { fun foo() }
interface B : A { fun bar() }

class Mixed(val a: AImpl) : B {
   override fun foo() { a.foo() }
   override fun bar() {}
}
manual delegation would solve the problem
also this works but feels redundant declaration:
Copy code
interface A { fun foo() }
interface B : A { fun bar() }

class Mixed(val a: AImpl) : B, A by a { // via B, A is already part of the interface definition, why I need to write it down again?
   override fun bar() {}
}
r
why I need to write it down again?
Because you're specifically delegating the implementation of
A
, not
B
.