Это становится немного более очевидным, когда вы расширяете (не каламбур) свой пример за пределы одного простого случая.
Множественное наследование:
class C[A] extends X with Y with Z
Примеси:
val x = new X with Y
Параметрирование:
class X[A <: B] extends Y[A]
Множественные (связанные) PARAMS Тип:
class X[A >: B, B](x: A, xs: Seq[B])
Контекст оценки:
class X[A : Manifest]
Посмотреть Bounds:
class X[A <% Ordered[A]]
Generic Методы:
class Foo[B] {
def bar[A <: B](x: A) = ...
}
Как вы можете видеть, отношения, которые могут быть указаны в качестве параметра типа намного богаче простой линейной иерархии, доступной при объявлении класса, особенно когда вы низкий для границ.
Стоит также отметить, что параметры универсального типа для классов или методов очень часто можно сделать вывод, что позволяет написать:
val myList = List(1, 2, 3)
вместо
val myList = List[Int](1, 2, 3)
Таким образом, способ, в котором нотации используются очень разные.
обновление
Один конкретный пример только на ум, демонстрирующий использование обеих нотаций одновременно и показывая, как они должны оставаться различны:
def someMethod[T <: Foo with Bar](x: T) = ...
Это требует, типа-парам T
быть подтипом что-то смешивание в обоих Foo
и Bar
.
То же самое относится и со структурными типами:
type Closable = { def close: Unit } //alias for a structural type
def someMethod[T <: Closable](x: T) = ...
++ 1 для разговора между классами и типами – 2010-11-27 12:33:29