Reputation: 33063
In Scala no methods can be invoked on the current instance when the superclass constructor is called. So there is no opportunity for a method to be invoked which will memorise the value that it is returning, in the current instance. How can I retain the arguments produced to give to a superclass constructor, while still using inheritance, as opposed to composition, and without modifying the source code of the class I'm inheriting from?
Upvotes: 1
Views: 317
Reputation: 33063
In Scala 2.8 and above, use an early definition:
class Foo(arg1: Type1, arg2: Type2) extends {
val arg3 = new Type3(arg1)
val arg4 = new Type4(arg2)
} with Bar(arg3, arg4)
This works even if Bar
is a class rather than a trait.
Upvotes: 2
Reputation: 33063
Create a companion object with a factory method. The factory method computes the arguments to pass them to the superclass constructor. But it doesn't do so directly, of course - it can't. Instead, it calls your primary constructor, which you can make private, like this:
class C private (private val superclassArg: ArgType) extends Super(superclassArg) { ... }
Unfortunately this solution isn't very compositional, because it doesn't allow you to inherit from C. Making the constructor of C public would, but it would still require duplicating code, and you could forget to preprocess the constructor argument. I suppose it depends whether you think it will always be essential for subclasses of C to preprocess the argument in this way.
Upvotes: 1
Reputation: 167891
You can also use
class Foo(arg1: Type1, arg2: Type 2)(
implicit computed: Hidden[(Type3,Type4)] = (new Type3(arg1), new Type4(arg2))
) extends Bar(computed._1, computed._2) { }
given
private[mypackage] class Hidden[A](val value: A) { }
implicit def i_can_hide_things[A](a: A) = new Hidden(a)
implicit def i_can_find_things[A](ha: Hidden[A]) = ha.value
Upvotes: 2
Reputation: 33063
Intersperse another class (here MemoBar
) into the inheritance hierarchy, like this:
class Foo(arg1: Type1, arg2: Type2) extends MemoBar(new Type3(arg1), new Type4(arg2)) {
}
class MemoBar(protected val arg3: Type3, arg4: Type4) extends Bar(arg3, arg4) {}
Then your arg3
and arg4
will be retained and visible only to subclasses of MemoBar
(in this case, just Foo
, but of course you could reuse MemoBar
if you faced the same problem with Bar
again).
Upvotes: 0