Невозможно создать черту без методов без пустого блока кода. - PullRequest
2 голосов
/ 28 февраля 2020

Я обнаружил интересное условие с чертами:

scala> trait Thing[A]
defined trait Thing

scala> val myThing: Thing[Int] = new Thing[Int]
       error: trait Thing is abstract; cannot be instantiated

scala> val myThing: Thing[Int] = new Thing[Int] { }
myThing: Thing[Int] = $anon$1@135f160e

Почему наличие блока кода позволяет мне создавать экземпляр черты Thing?

Ответы [ 3 ]

6 голосов
/ 28 февраля 2020

Эта особенность языка называется анонимный класс . Когда вы пишете new Thing[Int] { }, компилятор создает новый класс с именем $anon$1 (или что-то подобное), который расширяет Thing[Int], а затем создает новый экземпляр $anon$1.

3 голосов
/ 28 февраля 2020

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

Аналогичный вопрос размещен в другом месте:

2 голосов
/ 28 февраля 2020

Другой способ взглянуть на это - ключевое слово new вызывает конструктор , однако у trait нет конструктора, поэтому создание экземпляра

new Thing[Int]

невозможно. Но где находится конструктор в

new Thing[Int] { }

, спросите вы? Ну, «пустой блок кода» фактически определяет конструктор. Этот конструктор действительно не имеет операторов (кроме вызова супер-конструктора), однако теперь new, по крайней мере, должен что-то вызывать. Точно так же

class Bar
trait Qux

new Bar // ok because class has a constructor (by default)
new Qux // error because trait has no constructor

Точный термин для поиска в SLS: общее выражение создания экземпляра , как объяснено здесь .

...