В методе :: есть «Нижние границы типа»:

def ::[B >: A] (x: B): List[B] =
new scala.collection.immutable.::(x, this)

[B>: A] mean B - это родительский класс A, но почему объект дочернего класса может быть передан в методе ::?

class GP
class P extends GP
class C extends P

val li : List[P] = List[P](new P)
(new GP)::li // ok
(new C)::li  // why here ok? 

This (ndw C) :: li // почему здесь хорошо?, (new C) является объектом дочернего класса, а не суперклассом P, это не соответствует [B>: A ])?

liango

Ответов: 2

Ответы (2)

Как вы говорите, C не является родительским (или равным) P, поэтому C не может быть выбрано в качестве значения для В. Однако значения типа C могут быть переданы в методы, которые ожидают значения типа P (потому что C является дочерним классом), поэтому, если мы выберем B = P, получаем : :( x: P): List [P] и new C можно передать как значение для x. Вот что происходит, когда вы выполняете (новый C) :: li.

Вот почему результирующий тип List [P], а не List [C] (что было бы неверно), тогда как тип предыдущей строки Перечислите [GP], так как в этой строке нужно было выбрать B = GP, чтобы типы работали.

It's not an error because (new C) is an instance of C, and therefore of P; so, in that example, the B and A type-variables are both P.

(Your next question may be — if the lower type bound allows this, then what purpose does it serve? The answer is that it allows this:

val liC : List[C] = List[C](new C)
val liP : List[P] = (new P)::liC

(effectively "promoting" a List[C] to a List[P]) without allowing this:

val liP : List[P] = List[P](new P)
val liC : List[C] = (new C)::liP    // invalid! cannot downcast!

.)

2022 WebDevInsider