18
votes

I have seen few similar questions, but none had explained why delegation is limited to interfaces?

Most of the time in practice we have something that has actually no interface at all, it is a class that implements nothing but provides some functionality or implements an abstract class.

Is there any fundamental limitation that forces this to be limited to interfaces or can we expect kotlin to have unrestricted delegation in the future?

This is especially useful if we want to extend functionality of a class using composition not inheritance.

class A {}
class B(val a: A) : A by a {}
1

1 Answers

12
votes

When you delegate an interface, the class does still implement the interface. So for consistency, if you can delegate a class, it should work the same way. I.e.

class A(x: Int) {
  fun foo() = x
}

class B(val a: A) : A by a {}

needs to compile to

class B(val a: A) : A {
  override fun foo() = a.foo()
}

except this doesn't work:

  1. foo isn't open and can't be overridden.

  2. you need to call a constructor of A. class B(val a: A) : A(a.x) won't help either: x is not a member of A.

  3. What about equals and hashCode: are they delegated? Either decision would lead to weird consequences.