简体   繁体   中英

How do I pass an inherited variable into a Auxiliary constructor from a trait

I'm looking to get the value bork and pass it to a class into the class in the constuctor.

trait dog {
  lazy val bork = "bork"
}


class Animal(val firstName: String, dogCommand: DogCommand) extends dog{
  def this(firstName: String) {
    this(firstName, DogCommand(bork))
  }
  
  def getDogCommand(): Unit = {
    dogCommand.getCommand()
  }
}

case class DogCommand(command: String) {
  def getCommand() :Unit = {
      println(command)
  }
}

val myDog = new Animal("first")

myDog.getDogCommand()

I usually get - error: not found: value bork

The problem is that bork is a value on dog but there is no instance of dog available to read the bork from. this is a constructor so it doesn't have access to the value that is being constructed.

This is one solution that retains most of the original code:

trait dog {
  def bork = dog.DefaultBork
}

object dog {
  val DefaultBork = "bork"
}

class Animal(val firstName: String, dogCommand: DogCommand) extends dog {
  def this(firstName: String) = this(firstName, DogCommand(dog.DefaultBork))

  ...
}

You could consider removing the default value of bork in dog so that any class implementing the trait is required to provide a value for bork . (It can always use DefaultBork if it wants to retain the default value)

For one item, your this constructor is incorrect. I also renamed Dog . As for your lazy val that wouldn't work on a trait. See more here why scala don't allow define lazy val in trait? . Even if you make it non-lazy, that value is not initialized yet until construction when that val is not available, yet. Another problem would also be logic, an Animal is not Dog , but the other way around. Here is an alternative: https://scastie.scala-lang.org/WnhxzSn6QtOf5vo1epDDqQ Hope that helps. ;)

trait Dog {
  lazy val bork = "bork"
}


class Animal(val firstName: String, dogCommand: DogCommand) extends Dog {
  def this(firstName: String) = this(firstName, DogCommand(bork))
  
  def getDogCommand(): Unit = {
    dogCommand.getCommand()
  }
}

case class DogCommand(command: String) {
  def getCommand() :Unit = {
      println(command)
  }
}

val myDog = new Animal("first")

myDog.getDogCommand()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM