D#B
- это проекция типа, и это не то же самое, что и d.B
. У вас есть несоответствие типа, потому что в foo
, B
фактически означал this.B
, который, как сказано, не совпадает с D#B
(последний более общий). неформально, вы можете думать о D#B
как представляющие любой возможный типа, что абстрактный тип B
может принять для любого экземпляра D
, а d.B
является типом B
для конкретного экземпляра d
.
См. What does the `#` operator mean in Scala? и What is meant by Scala's path-dependent types? для некоторых контекстов.
Один из способов сделать это скомпилировать это путем изменения createB
«s типа возврата к d.B
:
def createB(): d.B
Однако во многих случаях такого решения является слишком ограничительным, потому что вы привязаны к конкретному экземпляру d
, который возможно, не то, что вы имели в виду. Другим решением является то, чтобы заменить абстрактный тип с параметром типа (хотя это более подробно):
trait A[B] {
def foo(b: B)
}
trait C[B, D <: A[B]] {
val d: D
def createB(): B
def bar() {
d.foo(createB)
}
}