0
votes

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.

1
Does val a: A not work for you? Also in Scala we define a value member in super class/trait using def instead of valSwiftMango
Do you want users of X to know which specific A did they got? or should they just depend on the interface?Luis Miguel Mejía Suárez
@texasbruce It shows 'Required: A, Found: G'Francisco Teixeira
@LuisMiguelMejíaSuárez No, they just need to get an implementation of A and use the func1 and func2. Regardless of whether it is class G or F, class Z must be able to use func1 and func2Francisco Teixeira

1 Answers

2
votes

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