Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kotlin: How can I avoid code duplication in constructors?

Often I find myself in a situation where I have a superclass that has lots of optional parameters, and those same parameters need to also be optional parameters in its subclasses.

For example, the superclass:

abstract class Plugin(val name: String, val version: String = "1.0",
                      val author: String = "", val description: String = "")

Extending this class is a pain. Here's an example subclass:

abstract class CyclePlugin(name: String, version: String = "1.0", author: String = "",
                       description: String = "", val duration: Int, val durationUnit: TimeUnit
                       = MILLISECONDS) : Plugin(name, version, author, description)

Note: I will answer this question with my solution. I am in search of a better solution.

like image 428
Jire Avatar asked Jan 24 '16 10:01

Jire


2 Answers

The way I normally solve this problem is by creating a data class to represent the parameters.

data class PluginInfo(val name: String, val version: String = "1.0",
                      val author: String = "", val description: String = "")

I then take this class as a parameter in the constructors.

abstract class Plugin(val info: PluginInfo)

abstract class CyclePlugin(info: PluginInfo, val duration: Int,
                           val durationUnit: TimeUnit = MILLISECONDS) : Plugin(info)

Then an example plugin can be implemented like this:

class ExamplePlugin : CyclePlugin(PluginInfo("Example Plugin", author = "Jire"), 8, TimeUnit.SECONDS)
like image 139
Jire Avatar answered Oct 28 '22 16:10

Jire


Like @miensol mentioned, you can define your properties outside of the constructor.

abstract class Plugin(val name: String) {

    open val version: String = "1.0"
    open val author: String = ""
    open val description: String = ""

}

Then you're able to define CyclePlugin with only the necessary name parameter:

abstract class CyclePlugin(name: String, val duration: Int,
                           val durationUnit: TimeUnit = MILLISECONDS) : Plugin(name)

Then for example, you can override some fields for ExamplePlugin:

class ExamplePlugin : CyclePlugin("Example Plugin", 8, TimeUnit.SECONDS) {

    override val author = "Giovanni"
    override val description = "This is an example plugin"

}
like image 41
Giovanni van der Neut Avatar answered Oct 28 '22 16:10

Giovanni van der Neut