2016-01-24 13 views
7

Spesso mi trovo in una situazione in cui ho una superclasse che ha molti parametri opzionali, e quegli stessi parametri devono essere anche parametri opzionali nelle sue sottoclassi.Kotlin: Come posso evitare la duplicazione del codice nei costruttori?

Per esempio, la superclasse:

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

Estendendo questa classe è un dolore. Ecco un esempio sottoclasse:

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) 

Nota: Risponderò a questa domanda con la mia soluzione. Sono alla ricerca di una soluzione migliore.

+1

Ancora un altro motivo per evitare l'ereditarietà :) Se questi parametri sono opzionali, perché usarli nel costruttore? Invece si potrebbe semplicemente dichiarare la proprietà regolare 'var optionalProperty: String? = "DefaultValue" 'nella classe base. – miensol

risposta

5

Come @miensol accennato, è possibile definire le proprietà di fuori del costruttore.

abstract class Plugin(val name: String) { 

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

} 

Allora sei in grado di definire CyclePlugin con solo il necessario name parametri:

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

Poi, per esempio, è possibile ignorare alcuni campi per ExamplePlugin:

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

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

} 
+0

Cosa succede se 'CyclePlugin' non è astratto e può essere inizializzato con quei parametri opzionali? – BakaWaii

5

Il modo in cui risolvo questo problema è creando una classe di dati per rappresentare i parametri.

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

Quindi prendo questa classe come parametro nei costruttori.

abstract class Plugin(val info: PluginInfo) 

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

Poi un esempio plugin può essere implementato in questo modo:

class ExamplePlugin : CyclePlugin(PluginInfo("Example Plugin", author = "Jire"), 8, TimeUnit.SECONDS) 
Problemi correlati