Var overriding def


#1
Welcome to Scala 2.12.4 (OpenJDK 64-Bit Server VM, Java 1.8.0_171).
Type in expressions for evaluation. Or try :help.

scala> trait A { def i: Int = 0 }
defined trait A

scala> trait B extends A { var i: Int = 1 }
<console>:12: error: overriding method i in trait A of type => Int;
 variable i needs `override' modifier
       trait B extends A { var i: Int = 1 }
                               ^

scala> trait B extends A { override var i: Int = 1 }
<console>:12: error: variable i overrides nothing
       trait B extends A { override var i: Int = 1 }
                                        ^

Ok, I saw it is a known issue that a var cannot override a def. Sometimes. Because a var counts as two methods. I’m still not sure why the compiler cannot be more relaxed in this case and allow it. At the least, the error messages could be clearer.


#2

link?


#3

Interesting example. I guess the first should say “the getter of variable i needs an override modifier” and the second “the setter of variable i overrides nothing”. Logically one should get an error since there are two methods defined simultaneously, one overriding and one not.

regards,
Siddhartha


#4

I saw some old posts bringing it up, like here and here. Not sure what the best link would be.


#5

I was going to say, making the messages more clear is a good first step, but really, I want my example to compile. But now it occurred to me that simply providing a setter to override makes the compiler happy! I wonder, why no one offered this solution in the posts I saw.

**Welcome to Scala 2.12.4 (OpenJDK 64-Bit Server VM, Java 1.8.0_171).
Type in expressions for evaluation. Or try :help.

trait A { def i: Int = 0; def i_=(i: Int): Unit = () }
defined trait A

trait B extends A { override var i: Int = 1 }
defined trait B


#6

Not an ideal solution, though: maybe the supertype only has a getter, and you cannot or do not want to add one.


#7

#8

Just for completeness, a clean way to do this is:

trait B extends A{
    var j: Int = 2
    override def i = j
}

which does mean that one must set j rather than i in a subclass.

regards,
Siddhartha


#9

Thanks, it’s neat that Martin says on the ticket, "This would need to be a (small) SIP. " Already in 2009, the process had progressed from the SID to the small SIP. Any SIP that is not small is Dotty. I suspect that SID stood for “Sudden Initiative Death”, because it was the quickest way to kill an initiative. A pillow also works, so they renamed it to the “Scala Initiative Pillow.”