Search code examples
guavakotlin

In Kotlin, how to delegate to an interface and provide only a no-arg public constructor?


The problem arises from the fact that Kotlin class delegation allows to delegate only to constructor parameters, thus seemingly forcing you to provide constructor with an argument.

Below is my original question pertaining to a concrete use case of this problem.


I want to do the following:

val myTable1: MyTable = MyTable()

where

  • MyTable inherits from ImmutableTable (src) or at least Table
  • and I do not have to manually delegate all the Table methods to some base implementation.

I also want to avoid the following:

val myTable2: MyTable = MyTable.build() 

i.e. I do not want to be forced to use companion objects / static factory methods.

I tried to extend ImmutableTable, but I am getting This type has a constructor, and thus must be initialized here.

I tried to extend Table interface and delegate to it (to avoid reimplementing methods) but then I am forced to provide an instance of Table as constructor parameter. I cannot just initialize it in init {} block.

Please see this gist for my exact attempts.

Kotlin version used: 1.0.2


Solution

  • As mentioned in comments, Guava has ForwardingTable that can accomplish this. But here's another option that should work even for interfaces where there isn't a "forwarding" version defined.

    class MyTable private constructor(table: Table<Int, Int, Int>) : Table<Int, Int, Int> by table {
    
        constructor() : this(TreeBasedTable.create()) // or a different type of table if desired
    
    }