Использование конструктора scala для установки переменной, определенной в trait - PullRequest
43 голосов
/ 18 ноября 2011

Если я правильно понимаю, черты - это самая близкая вещь к интерфейсам Java, и конструкторы классов автоматически устанавливают переменные.

Но что, если у меня есть класс, который расширяет черту и имеет конструктор, который устанавливает переменную изчерта, что-то вроде:

trait Foo {
    var foo: String
}

class Bar (foo: String) extends Foo { /* ... */ }

Где я хочу, чтобы строка черты foo была установлена, когда я делаю объект Bar.

Компилятор, кажется, дает мнеошибки по этому поводу.Как правильно достичь этого?

Ответы [ 2 ]

33 голосов
/ 18 ноября 2011
trait Foo { var foo: String = _ }
class Bar(foo0: String) extends Foo { foo = foo0 }

Эта черта объявляет неинициализированный var; затем класс устанавливает его равным входному параметру.

С другой стороны,

trait Foo {
  def foo: String
  def foo_=(s: String): Unit
}
class Bar(var foo: String) extends Foo {}

объявляет пару getter / setter, соответствующую foo, которые установлены классом.

27 голосов
/ 18 ноября 2011

Bar должен определять абстрактное значение var foo в Foo (будет таким же для val). Это можно сделать в конструкторе

class Bar(var foo: String) extends Foo{...}

(конечно, это можно сделать и в теле Bar). По умолчанию параметры конструктора будут преобразованы в приватные val, если это необходимо, то есть если они используются вне кода инициализации в методах. Но вы можете заставить поведение пометить их val или var и, возможно, контролировать видимость, как в

class X(protected val s: String, private var i: Int)

Здесь вам нужен общедоступный var для реализации Foo.

...