Circular definitions are not a problem in this case, as the return type is not circular, and the implementation can be resolved in a second pass after the types are resolved.
For example--and note that I'm wrapping everything in an object so that the REPL will consider it all at once:
object Example {
abstract class E {
def a: Int
def e: E = new AE(2)
}
class AE(val a: Int) extends E { }
}
and this works as expected:
scala> val ae = new Example.AE(0)
ae: Example.AE = Example$AE@57240e
scala> ae.a
res1: Int = 0
scala> ae.e.a
res2: Int = 2
My guess is that while you're typing it in, you're trying to get the REPL to accept only part of the circular definition, or you're leaving out something that allows the circularity to be resolved in types (e.g. if you type the return as AbstractElement
not Element
, that would be confusing!).
Anyway, the code as-is looks okay to me.