简体   繁体   中英

Scala object extends abstract class/trait, access companion class fields

Currently I have the following code:

case class Foo(text: String, tag: Tag) {...}
object Foo {
    def doSomething(fooSeq: Seq[Foo]) = fooSeq.map(f => f.tag)
    def doSomethingElse() = {...}
}

I would like to move the doSomething method into an abstract class/trait so I can parametrize the tag and reuse the code later. Ideally, I'd like to do something like this:

case class Foo(text: String, tag: Tag) {...}
object Foo extends TraitFoo[Tag] {
    def doSomethingElse() = {...}
}

---------------in another file----------------

trait TraitFoo[T] = {
    def doSomething(fooSeq: Seq[TraitFoo[T]]) = fooSeq.map(f => f.tag)
}

However, the compiler complains that it cannot recognize f.tag inside TraitFoo .

I considered using an abstract class, but that also causes issues, because my object Foo does not need a constructor. It only needs to access the fields in its companion class.

Perhaps you can add another type parameter to TraitFoo with a structural bound? Like this:

trait TraitFoo[A, B <: { def tag: A }] {
    def doSomething(fooSeq: Seq[B]): Seq[A] = fooSeq.map(f => f.tag)
}

case class Foo(text: String, tag: Tag) { ... }
object Foo extends TraitFoo[Tag, Foo] {
    def doSomethingElse() = { ... }
}

This would be essentially the same as this, but a bit less verbose / less explicit:

trait Tagged[A] {
    def tag: A
}
trait TraitFoo[A, B <: Tagged[A]] {
    def doSomething(fooSeq: Seq[B]): Seq[A] = fooSeq.map(f => f.tag)
}

case class Foo(text: String, tag: Tag) extends Tagged[Tag] { }
object Foo extends TraitFoo[Tag, Foo] {
    def doSomethingElse() = { }
}

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