Семантика абстрактных трейтов в Scala

Мне интересно, какова семантика использования ключевого слова abstract в сочетании с trait.

Если трейт не определяет никаких абстрактных методов, ключевое слово abstract не мешает мне создать экземпляр:

scala> abstract trait T
defined trait T

scala> new T{}
res0: java.lang.Object with T = $anon$1@12cd927d

С другой стороны, если трейт определяет абстрактный метод, я не могу создать экземпляр (без реализации этого метода, конечно) независимо от того, присутствует ключевое слово abstract или нет:

scala> abstract trait T { def foo : Unit }
defined trait T

scala> new T{}
<console>:9: error: object creation impossible, since method foo in trait T of type =>    Unit is not defined
              new T{}
                  ^

scala> trait T { def foo : Unit }
defined trait T

scala> new T{}
<console>:9: error: object creation impossible, since method foo in trait T of type =>     Unit is not defined
              new T{}
                  ^

Так для чего же нужно ключевое слово abstract перед trait?


person Frank    schedule 19.02.2012    source источник
comment
Вы не можете создать экземпляр черты. Когда вы говорите new T{}, вы создаете анонимный объект, который смешивает черту T.   -  person kiritsuku    schedule 19.02.2012


Ответы (2)


Это не имеет никакого эффекта, трейты автоматически абстрагируются.

Модификатор abstract используется в определениях классов. Это избыточно для трейтов и обязательно для всех других классов, которые имеют неполные члены.

http://www.scala-lang.org/docu/files/ScalaReference.pdf

person retronym    schedule 19.02.2012

Вы не создаете экземпляр черты. Черты не могут быть созданы.

Вы создаете экземпляр анонимного класса, расширяющего черту.

В целом,

new __t__

эквивалентно

{ class __anonymous__ extends __t__; new __anonymous__ }

(где __anonymous__ — это свежее имя анонимного класса, недоступного для пользовательской программы).

Это подробно описано в разделе 6.10 Выражения создания экземпляров спецификации языка Scala.

Итак, причина, по которой вы можете создать экземпляр в первом случае, заключается в том, что вы создаете не экземпляр признака (который является абстрактным), а объект (который не является).

Во втором случае причина, по которой вы не можете создать экземпляр, заключается в том, что если вы наследуете от чего-то, будь то трейт или класс, вам в конечном итоге придется реализовать его абстрактные методы где-то в цепочке наследования, чтобы создать его экземпляр. . В первом случае нет необходимости реализовывать абстрактные методы.

Само ключевое слово abstract не имеет значения: признаки неявно абстрактны, ключевое слово избыточно.

person Jörg W Mittag    schedule 19.02.2012
comment
Я думаю, вы имеете в виду, что он создает анонимный класс, который имеет трейт как миксин. - person oxbow_lakes; 19.02.2012
comment
Извините, да. Объект, являющийся экземпляром анонимного класса, который является подклассом признака. Фу. - person Jörg W Mittag; 31.03.2016