Scala: override implicit var in constructor in both parent class and child class?

I have a class that takes an implicit parameter that is used by functions called inside the class of methods. I want to be able to either override this implicit parameter, and have both the class and its inherited parent class refer to the same new implicit object.

makes Parent an implicit var and a parameter that successfully overrides the implicit in the parent, but not the child, for the new value.

(this is similar to scala: override the implicit parameter in the constructor , with the exception of the added restriction that overriding affects both the child class and the parent class.)

eg:

def outside(implicit x: Boolean) { println(x) } class Parent(implicit var x: Boolean) { def setImplicit() { x = true } def callOutside { outside } } class Child(implicit x: Boolean) extends Parent { override def callOutside { outside } } 

and then:

 scala> val a = new Parent()(false) a: Parent = Parent@c351f6d scala> a.callOutside false scala> a.setImplicit() scala> a.callOutside true // <-- sees the new implicit correctly scala> val b = new Child()(false) b: Child = Child@68331dd0 scala> b.callOutside false scala> b.setImplicit() scala> b.callOutside false // <-- wrong, desire "true" instead 

Is there a way to get the desired behavior? doing something like that both parent and child are implicit, like var doesn't seem to work. thanks!

+4
source share
1 answer

You could just

 class Parent(x0: Boolean) { implicit var x = x0 ... } 

unless you really need a class parameter, which should be implicit. I guess you do it.

One option is to place the implications in a companion object. For instance:

 class Parent(x0: Boolean) { implicit var x = x0 def setImplicit { x = true } def outsideCall { outside } } object Parent { def apply(implicit x: Boolean) = new Parent(x) } class Child(x0: Boolean) extends Parent(x0) { def callOutside { outside } } object Child { def apply(implicit x: Boolean) = new Child(x) } 

Alternatively, you can create a private main constructor for Child (styled in some way so that it is not ambiguous with implicit) and use implicit for the secondary constructor:

 class Child private (b: Boolean, u: Unit) extends Parent()(b) { def this()(implicit x: Boolean) = this(x,()) def callOutside { outside } } 
+1
source

All Articles