Я хотел бы определить иерархию наследования классов, чтобы параметризованный метод имел тип параметра между моим первым базовым классом и текущим:

class A {
 var x; 
}
class B(parent:A = null) extends A {
 var y;
 protected def method[/* T where, T is subclass of A but super class of type.this */](param:T):Unit = {}
}
class C(parent:B = null) extends B {
 var z
 protected override def method[/* T where, T is subclass of A but super class of type.this */](param:T):Unit = {}
}

Это возможно? Есть ли причина, по которой я не должен пытаться достичь этого (архитектурные соображения или любые другие)?

0
TrN 11 Янв 2014 в 19:22
2
Один небольшой комментарий, пожалуйста, не используйте null в Scala, если вы можете помочь избежать этого. Вот почему они сделали типы Option.
 – 
wheaties
11 Янв 2014 в 19:31
Хорошо, спасибо, запомню :)
 – 
TrN
11 Янв 2014 в 19:32

1 ответ

Лучший ответ

Вы можете использовать привязку типа >: this.type:

class A
class B extends A
class C extends B { def method[T >: this.type <: A](a: T) = a }
class D extends C

Таким образом, вы не можете вызвать метод на C с параметром типа D:

scala> new C().method[D](new D)
<console>:12: error: type arguments [D] do not conform to method method's type parameter bounds [T >: C <: A]
              new C().method[D](new D)
                            ^

Но вы можете вызвать его с параметром типа D на D:

scala> new D().method[D](new D)
res0: D = D@49df83b5

Обратите внимание, что любой экземпляр D также является экземпляром C, поэтому new C().method(new D) (без параметра типа) будет скомпилирован как new C().method[C](new D).

7
senia 11 Янв 2014 в 20:15
Может также быть: [A>: T>: this.type]?
 – 
Vincenzo Maggio
11 Янв 2014 в 19:47
1
@VincenzoMaggio: нет, синтаксис такой ParamName (>: UpperBound)? (<: DownBound)?.
 – 
senia
11 Янв 2014 в 19:49
Это гораздо лучший ответ, чем мой!
 – 
wheaties
11 Янв 2014 в 20:03