Краткая версия заключается в том, что вы создали псевдоним типа для структурного типа (создание которого невозможно).
Это упрощенная версия того, что вы сделали (не работает):
scala> import collection.mutable._
import collection.mutable._
scala> type ObservableHashSet[T] = HashSet[T] with ObservableSet[T]
defined type alias ObservableHashSet
scala> new ObservableHashSet[String]
<console>:12: error: class type required but scala.collection.mutable.HashSet[String] with scala.collection.mutable.ObservableSet[String] found new ObservableHashSet[String]
Теперь ошибка имеет какой-то смысл, и позвольте мне объяснить, почему.
С type ObservableHashSet[T] = HashSet[T] with ObservableSet[T]
вы определяете псевдоним типа для чего-то, что не является конкретным типом (или, как говорится в сообщении об ошибке, а не "типом класса"), поэтому вы не можете создать его экземпляр new
.
Но это (с промежуточным шагом, когда мы создаем тип класса) работает:
scala> class ObservableHashSet[T] extends HashSet[T] with ObservableSet[T]
defined class ObservableHashSet
scala> type obs[T] = ObservableHashSet[T]
defined type alias obs
scala> new obs[String]
res1: ObservableHashSet[String] = Set()
Итак, вопрос: почему scala позволяет вам создавать псевдоним типа, который вы не можете создать?
Ну, type ObservableHashSet[T] = HashSet[T] with ObservableSet[T]
это структурный тип. Хотя, как вы видели в первом фрагменте кода, вы не можете создать его экземпляр, вы все равно можете использовать его: например, наложить структурное ограничение на аргумент функции.
Взгляните:
scala> type ObservableHashSet[T] = HashSet[T] with ObservableSet[T]
defined type alias ObservableHashSet
scala> def test(obsHashSet: ObservableHashSet[String]) : String = {"bingo!"}
test: (obsHashSet: ObservableHashSet[String])String
scala> test(new HashSet[String] with ObservableSet[String])
res4: String = bingo!
но если мы попытаемся вызвать test с аргументом, который не соответствует структурному типу, мы получим несоответствие типов:
scala> test(new HashSet[String])
<console>:13: error: type mismatch;
found : scala.collection.mutable.HashSet[String]
required: ObservableHashSet[String]