Следующий класс Scala:
class Foo[+T <: Bar] extends FooBase ...
эффективно определяет иерархию типов, которая имеет Foo[Bar] в качестве корня, т. е. любой допустимый Foo[X] будет присваиваться значению или переменной Foo[Bar]:
val v1: Foo[Bar] = new Foo[SubBar1]();
val v2: Foo[Bar] = new Foo[SubBar2]();
FooBase находится дальше и может также подразумевать объекты, которые не являются Foo — следующее показывает проблему:
class Trouble extends FooBase ...
val iOnlyWantFooHere: FooBase = new Trouble();
... а также FooBase не знает о типе T, поэтому его члены не могут указать его, и мне пришлось бы переопределить эти определения в Foo, чтобы специализировать их:
class FooBase {
def ohNoIDontKnowTheType: Bar;
}
class Foo[+T <: Bar] extends FooBase {
override def ohNoIDontKnowTheType: T = ...;
}
Есть и другие способы обойти эту проблему, но суть должна быть ясна.
Наконец, мой актуальный вопрос заключается в том, что является корнем следующей иерархии:
class Foo[+T <: Foo[T]] extends FooBase ...
Опять же, не говорите мне FooBase, потому что это не так. Да, я мог бы вставить другой класс специально для этой цели, но это все еще не верный ответ, как указано выше.
Scala не любит просто Foo
(без параметра типа), и это не Foo[_]
, так как тогда доступ к методам, возвращающим значение типа параметра типа, на самом деле будет Any
, а не Foo
. Конечно, мы не можем сделать и Foo[Foo]
, так как для второго также отсутствует параметр типа, а Foo[Foo[_]]
или Foo[Foo[Foo[Foo[_]]]
дает нам только определенное количество уровней.
Есть ли вообще ответ или Scala не поддерживает это?
Заранее спасибо!