Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

scala inheritance issue: val vs. def

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?

like image 949
Vadim Samokhin Avatar asked Jan 29 '12 07:01

Vadim Samokhin


People also ask

What is the difference between DEF and Val in Scala?

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.

How do I override Val in Scala?

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.

What is def Scala?

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 -----

Does Scala allow multiple inheritance?

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.


1 Answers

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 vals. Always use abstract defs and lazy vals.

like image 67
missingfaktor Avatar answered Sep 21 '22 05:09

missingfaktor