So here is the problematic code:
trait World {
type State
def dynamics(s: State): State
// ...
}
trait GridWorld extends World {
class State {...} // concrete
def dynamics(s: State) = s // concrete
// some other staff still abstract
}
trait SimpleGridWorld extends GridWorld {
class State extends super.State {...} // concrete
def foo {dynamics(new State)} // compiler error
}
The compiler says that, dynamics
in both World
and GridWorld
match the signature. However, in World
it is abstract and then implemented in GridWorld
, so it seems to me that it is clear that I am calling GridWorld.this.dynamics
.
Another thing I noticed is that, if I remove the extends super.State
in SimpleGridWorld
, everything works fine (which I don't understand why, and I do need the functionalities defined in GridWorld.State
here). Any explanations? Thanks!
UPDATE
Anyway I am seeing my design pattern quite weird, since if State
in SimpleGridWorld
does not inherit GridWorld.this.State
, dynamics
would refer to the unimplemented one defined in the root trait World
(which makes sense because the implementation in GridWorld
may use the functionalities of GridWorld.this.State
which may not exist in SimpleGridWorld.this.State
). But what I want is:
XXXWorld.this.State
must inherit its super.State
(or just use it)dynamics
always refers to super.dynamics
if implemented in the super trait/class unless overrided here.How can I do this? I think it is not a totally irrelevant question, and probably the answer to the previous one would tell me how to redesign my pattern.
How about:
trait World {
type State
def dynamics(s: State): State
}
trait GridWorld extends World {
type State = MyState
class MyState {} // concrete
def dynamics(s: State) = s // concrete
}
trait SimpleGridWorld extends GridWorld {
class MyState extends super.MyState {} // concrete
def foo {dynamics(new MyState)} // compiler error; ok
}