Francisco Teixeira
Francisco Teixeira

Reputation: 35

How can I assign a val with the implementation of a trait?

I have the following trait and classes:

trait A{
  def func1: String
  def func2: Int
}
class F extends A{
  def func1: String = ???
  def func2: Int = ???
}
class G extends A{
  def func1: String = ???
  def func2: Int = ???
}

And I want to create the following trait and class:

trait X{
  val a: ***
}
class Z extends X{
  override val a = new G
}

What do I need to write on '***' in trait X so that I can assign val a with a class F or G ? Thank you.

EDIT

Sorry, I forgot to mention that trait A is A[Any] and traits F and G can be 'F extends A[String]' and 'G extends A[Int]'. In other words, the classes can extends the trait A with different types of parameters.

Upvotes: 0

Views: 311

Answers (1)

SwiftMango
SwiftMango

Reputation: 15284

Re. your edit, your code fails because trait A only takes type parameter of a fixed type. If you declare base class having a A[Any], you cannot override it with a A[Int] or A[String]. There are two ways to make your code works.

One is to make trait A type argument covariant, so that you can override with subclass of the type argument you declared in base class (note the + in trait A definition):

  trait A[+T]
  class F extends A[String]
  class G extends A[Int]
  
  trait X {
    val a: A[Any]
  }
  
  class Z extends X {
    val a = new G
  }

See here: Sample

Another way to work is to declare a as a A[_] (_ means it takes any type as a parameter, which is different from Any):

  trait A[T]
  class F extends A[String]
  class G extends A[Int]
  
  trait X {
    val a: A[_]
  }
  
  class Z extends X {
    val a = new G
  }

See here: Sample

Upvotes: 2

Related Questions