Это очень сильно зависит от вашего варианта использования. Например
trait TraitClass[A <: TraitObject[_]] {
def getA: A
def name: String = getA.getName
}
trait TraitObject[A <: TraitClass[_]] {
def apply: A
def getName: String
}
case class Foo(a: Int) extends TraitClass[Foo.type] {
def getA = Foo
}
object Foo extends TraitObject[Foo] {
def getName = "foo"
def apply = Foo(12)
}