rgamber
rgamber

Reputation: 5849

Extend trait with private constructor parameter

In Scala, how can I extend a trait in a class with private constructor parameter that is defined in the trait?

trait Parent {
  protected def name: String
  require(name != "", "wooo problem!")
}

class Child(private val name: String) extends Parent {
  println("name is " + name)
}

The above class gives an error:

class Child needs to be abstract, since method name in trait Parent of type ⇒ String is not defined.

Of-course I can:

  1. make the Child class abstract,
  2. define it without using the private in the constructor like class Child(val name: String).
  3. make the Parent an abstract class instead of a trait

But with the above implementation, is there no way I can have a private constructor parameter while extending a trait? Note that I want the variable to be private so that I should not be able to do childInstance.name.

Upvotes: 5

Views: 1199

Answers (2)

marios
marios

Reputation: 8996

If you have an abstract method in a trait, then all the derived classes need to have the same (or more permissive) modifier (in your case at least protected) for the abstract methods.

trait Parent {
  protected def name: String
  require(name != "", "wooo problem!")
}

class Child(private val privateName: String) extends Parent {
  override protected def name: String = privateName
  println("name is " + name)
}

You can keep your constructor private, but you need to define the override protected def name: String and make use of the private value of your constructor.

Upvotes: 1

Sami Badawi
Sami Badawi

Reputation: 1032

Try this

  trait Parent {
    protected def name: String
    require(name != "", "wooo problem!")
  }

  class Child(override protected val name: String) extends Parent {
    val publicVar = "Hello World"
    println("name is " + name)
  }

  def main(args: Array[String]): Unit = {
    val child = new Child("John Doe")
    println(child.publicVar)
    println(child.name) // Does not compile
  }

You will not be able to access to child.name

Upvotes: 2

Related Questions