Ken Zira
Ken Zira

Reputation: 1176

Kotlin secondary constructor with generic type

In java

I can achieve two constructors like

public TargetTitleEntryController() { }

public <T extends Controller & TargetTitleEntryControllerListener> TargetTitleEntryController(T targetController) {
        setTargetController(targetController);
}

I want to convert it to Kotlin

class TargetTitleEntryController ()

with the secondary constructor. I don't know how to declare with generic type like Java counterpart.

Upvotes: 10

Views: 2348

Answers (3)

tbrush
tbrush

Reputation: 246

There is no intersection types in Kotlin (sad)

But there is Generic constraints (hope)

But Generic constraints not applicable in the secondary constructor (sad)

But you can simulate secondary constructor in a companion object using Invoke operator overloading (workaround):

class TargetTitleEntryController {

    // ...

    companion object {

        operator fun <T> invoke(targetController: T): TargetTitleEntryController
                where T : Controller,
                      T : TargetTitleEntryControllerListener {
            return TargetTitleEntryController().apply {
                setTargetController(targetController)
            }
        }
    }
}

Upvotes: 9

raquezha
raquezha

Reputation: 383

You can do it like this :)

class TargetTitleEntryController <T>() : Controller() where T: Controller, T: TargetTitleEntryControllerListener<T> {

 constructor(target: T) : this() {
        targetController = target
    }
}

you can implement it in your parent controller like this:

class TargetDisplayController : Controller(), TargetTitleEntryControllerListener<TargetDisplayController> {

  var targetTitleEntryController = TargetTitleEntryController(this)

  override fun onTitlePicked(String option) {

  }

  override fun onAttach(view: View) {
  // push controller here
  }
}

Upvotes: 0

gil.fernandes
gil.fernandes

Reputation: 14601

Here is an example where you specify a Type T which implements two interfaces (CharSequence, Runnable):

class Person<T>(val name: String) where T : CharSequence, T : Runnable {
    constructor(name: String, parent: T) : this(name) {
    }
}

So actually something like this should work:

class TargetTitleEntryController<T> () where T : Controller, T : TargetTitleEntryControllerListener {
    constructor(targetController: T) : this() {
    }
}

Upvotes: 2

Related Questions