Writing a simple example from Odersky's book resulted in the following problem:
// AbstractElement.scala
abstract class AbstractElement {
val contents: Array[String]
val height: Int = contents.length // line 3
}
class UnifiedElement(ch: Char, _width: Int, _height: Int) extends AbstractElement { // line 6
val contents = Array.fill(_height)(ch.toString() * _width)
}
object AbstractElement {
def create(ch: Char): AbstractElement = {
new UnifiedElement(ch, 1, 1) // line 12
}
}
,
// ElementApp.scala
import AbstractElement.create
object ElementApp {
def main(args: Array[String]): Unit = {
val e1 = create(' ') // line 6
println(e1.height)
}
}
The compiler throws the following trace:
Exception in thread "main" java.lang.NullPointerException
at AbstractElement.<init>(AbstractElement.scala:3)
at UnifiedElement.<init>(AbstractElement.scala:6)
at AbstractElement$.create(AbstractElement.scala:12)
at ElementApp$.main(ElementApp.scala:6)
at ElementApp.main(ElementApp.scala)
So the compiler thinks that contents is still null, but I defined it in UnifiedContainer!
Things get even more weird when I replace val with def and evrth works perfect!
Could you please xplain this behaviour?
val evaluates when defined. def evaluates on every call, so performance could be worse than val for multiple calls. You'll get the same performance with a single call.
In order to execute a Field Overriding, we need to override variables that are declared utilizing only the val keyword in both super class as well as sub-classes. Field overriding cannot override var, because we can both read as well as write var.
def is the keyword you use to define a method, the method name is double , and the input parameter a has the type Int , which is Scala's integer data type. The body of the function is shown on the right side, and in this example it simply doubles the value of the input parameter a : def double(a: Int) = a * 2 -----
Multiple Inheritance Multiple inheritance is the type of inheritance where the subclass inherits directly from more than one class. In Scala, this is not achievable with classes. Instead, multiple inheritance is supported via traits.
Here is a great article by Paul P that explains the initialization order intricacies in Scala. As a rule of thumb, you should never use abstract val
s. Always use abstract def
s and lazy val
s.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With