Reputation: 101149
Suppose I have the following class heirarchy:
class A()
class B(a:A)
class C(b:B)
class BaseClass(b:B, c:C)
Now I want to implement a subclass of BaseClass, which is given an instance of A, and constructs instances of B and C, which it passes to its superclass constructor.
If I could use arbitrary expressions, I'd do something like this:
b = new B(a)
c = new C(b)
super(b, c)
Because the second argument to the parent constructor depends on the value of the first argument, though, I can't see any way to do this, without using a factory function, or a gratuitous hack, such as :
class IntermediateSubclass(b:B) extends BaseClass(b, new C(b))
class RealSubclass(a:A) extends IntermediateSubclass(new B(a))
Is there clean way to do this?
Upvotes: 4
Views: 3053
Reputation: 26486
Probably the best way to handle this sort of situation is by writing a factory method in the companion object for the subclass of BaseClass you want to write.
class A()
class B(a:A)
class C(b:B)
class BaseClass(b:B, c:C)
class SBC private (a: A, b: B, c: C)
extends BaseClass(b, c)
object SBC
{
def
apply(a: A): SBC = {
val b = new B(a)
val c = new C(b)
new SBC(a, b, c)
}
}
You can make any of those constructor parameters into fields without affecting anything (by prefixing with val
, if you're not familiar with that syntax):
class A()
class B(val a: A)
class C(val b: B)
class BaseClass(val b: B, val c: C)
class SBC private (val a: A, b: B, c: C)
extends BaseClass(b, c)
object SBC
{
def
apply(a: A): SBC = {
val b = new B(a)
val c = new C(b)
new SBC(a, b, c)
}
}
Now new instances of SBC
can be created with this sort of expression: SBC(aValue)
(regardless of whether the val
s are used).
scala> val a1 = new A
a1: A = A@14a8f44
scala> val sbc1 = SBC(a1)
sbc1: SBC = SBC@7d8bb
scala> sbc1.a
res0: A = A@14a8f44
scala> sbc1.b
res1: B = B@c7272
scala> sbc1.c
res2: C = C@178743b
Upvotes: 7