Zyga Zyga - 28 days ago 16
Scala Question

Override trait's generic method without casting

I was planning to have a trait with "value" attribute that can be extended by multiple classes. I need to then be able to compare different instances of that trait between each other. Firstly I want to check the value defined on the trait - if thats the same across two instances, then I want to trigger child-specific method that will compare two child instances of the same type with each other.

I hope I explained that clearly enough...

I have below code written, but the ChildOne class doesnt compile - the error I am getting:


class ChildOne needs to be abstract, since method childCheck in trait
ParentType of type (other: ChildOne.this.T)Boolean is not defined
(Note that ParentType.this.T does not match com.cards.ChildOne)


trait ParentType {
val value: Int
type T <: ParentType

def parentCheck(other: T): Boolean = {
if (this.value == other.value) childCheck(other)
else this.value > other.value
}

def childCheck(other: T): Boolean
}

case class ChildOne(name: String) extends ParentType {
val value = 1

override def childCheck(other: ChildOne): Boolean = {
true //some custom logic for each child...
}

}


I could change the parameter of child's method to ParentType and then cast it, but I wanted to avoid that and I am wondering is there a better way of doing what I want to achieve?

Any help appreciated.

Answer

You declare an abstract type T in ParentType, without overriding it in ChildOne. You can fix this easily by overriding T in ChileOne:

case class ChildOne(name: String) extends ParentType {
  val value = 1
  override type T = ChildOne  // <----

  override def childCheck(other: ChildOne): Boolean = {
    true //some custom logic for each child...
  }
}