npace
npace

Reputation: 4258

How to mix multiple parent class constructors with val in child class

Suppose I have a class Parent that has four fields A, B, C and D, such that C and D are optionally passed or initialized with default implementations:

open class Parent(val a: A, val b: B, val c: C, val d: D) {
    constructor(a: A, b: B, c: C): this(a, b, c, DImpl()){}
    constructor(a: A, b: B): this(a, b, CImpl(), DImpl()){}
}

I need to extend this class and add another field to the child class:

class Child: Parent {
     val e: E // How do I initialize this?
}

Passing a val to a secondary constructor doesn't work, and neither does using the init{} block.

Passing a val to the primary constructor could work, but then I lose the delegation to the secondary constructors in the Parent class - I need to use all the Parent constructor with all the params or duplicate the secondary constructors, leaking implementation details to the Child class.

This should be simple, am I missing something here?

Upvotes: 4

Views: 322

Answers (2)

yole
yole

Reputation: 97338

If you do need to use secondary constructors, and can't use default values as suggested by @Ingo Kegel, you can initialize the e field just like you would do this in Java, by assigning the parameter value to the property:

class Child: Parent {
    val e: E

    constructor(a: A, b: B, c: C, d: D, e: E) : super(a, b, c, d) {
        this.e = e
    }
}

Upvotes: 8

Ingo Kegel
Ingo Kegel

Reputation: 48105

You can use default values instead of secondary constructors:

open class Parent(val a: A, val b: B, val c: C = CImpl(), val d: D = DImpl())
class Child(a: A, b: B, val e: E): Parent(a, b)

Upvotes: 7

Related Questions