0

I have some objects that implement a trait. I am trying to have a val that is static and common to all of these objects. I have read that the way to do this is to use a companion object for the trait. I have used the following:

trait Test

object Test extends Test{
  val a = 1
}

object Test2 extends Test{
  def test = {
    val b = a
  }
}

However, in the line val b = a I get a "not found: value a" error. I would appreciate some help on how to fix this.

Community
  • 1
  • 1
Eduardo
  • 8,362
  • 6
  • 38
  • 72

1 Answers1

3

Members of companion objects are by default not visible to anyone, even their companion classes. So you need an explicit import:

trait Test

object Test extends Test{
  val a = 1
}

object Test2 extends Test{
  import Test._

  def test = {
    val b = a
  }
}

I don't know if there is a nice way to do it without an import in every subclass...

ghik
  • 10,706
  • 1
  • 37
  • 50
  • That worked. Thank you. What the difference between `object Test extends Test` and `object Test` alone? Both seem to work the same. – Eduardo Jan 24 '13 at 14:38
  • `object Test` is a companion object of `class Test` (its companion class). Their names in scala are the same but they are two separate classes (and `object Test` is also a singleton). So by typing `object Test extends Test` you just make that singleton extend `class Test`. In the case above, there is no reason to do it, though. – ghik Jan 24 '13 at 14:44
  • Is there any value in having it as a companion object? If I name it `TestX` and do the import, it still works. – Eduardo Jan 24 '13 at 14:51
  • Visibility is only about scope (and / or `import`s). Accessibility is subject to protection levels such as `private` or `protected` and the relaxation of those controls for companions. – Randall Schulz Jan 24 '13 at 16:42
  • "I don't know if there is a nice way to do it without an import in every subclass..." You could add `def test = Test.test` to the trait. – Alexey Romanov Jan 24 '13 at 16:46
  • @AlexeyRomanov Yes, but I would have to do it with every single member that I want to use. – ghik Jan 24 '13 at 16:48
  • 1
    @Eduardo In your case, there is no technical difference between having it in companion object and any other object. However, usage of companion object for such case is probably more idiomatic and natural. Also, note that from Java, members of `object Test` will be visible as static members of `class Test`. It would make more difference if you e.g. wanted to define some implicit parameters or conversions in the object. I won't delve into details here, but this is related to so called _implicit scope_ and influences rules of implicit parameters/conversions visibility. – ghik Jan 24 '13 at 16:58