Scala также имеет POJO-подобные идиомы, но они отличаются от JavaBeans, и Scala делает акцент на разных аспектах.
Scala имеет различные соглашения об именах:
def foo: Foo //Foo getFoo() in Java
def foo_=(foo: Foo) //void setFoo(Foo foo) in Java
Таким образом, вы всегда можете написать obj.foo
и obj.foo = bar
, даже если вы решите переключиться с геттеров / сеттеров на прямой доступ к полю и наоборот.Это называется принцип унифицированного доступа .
В связи с совместимостью с Java введена аннотация @BeanProperty
:
@BeanProperty var foo: Foo = _
приведенный выше код несоздает только Scala-подобные геттеры / сеттеры, но также и Java-подобные, поэтому все фреймворки Java работают без проблем.
Scala вынуждает вас выбирать между переменными (var
) и значениями (val
), поэтому вы гораздо чаще пользуетесь неизменяемыми объектами
Я действительно предпочитаю неизменные объекты и инициализацию в конструкторе, что было очень легко сделать в Scala:
class Foo(val age: Int, val name: String)
или даже (val
по умолчанию в case
классах):
case class Foo(age: Int, name: String)
Этот фрагмент кода великолепен своей простотой.Тем не менее, если вам нужно взаимодействовать с Java-фреймворками, вам все равно нужны не требующий аргументов конструктор и сеттеры:
public class Foo(var age: Int, var name: String) {
def this() {
this(0, "")
}
}
Примечание val
заменяется на var
.
Модификаторы доступа в Scala имеют немного лучшие значения по умолчанию по сравнению с Java:
class Foo(var a: Int, x: Int) {
var b: Int = _
private var c: Int = _
private[this] var d: Int = _
def twisted = a + b + c + d + x
}
Переменные a
и b
станут полями private
с public
получателями / установщиками (поля являются частными дляпо умолчанию методы общедоступны).c
и d
также являются частными переменными.Но дополнительный private[this]
делает d
доступным непосредственно внутри класса, а не частным получателем / установщиком.
Поскольку x
используется где-то рядом с конструктором, Scala автоматически создает личное поле для него какЧто ж.Однако никакие геттеры / сеттеры не генерируются, доступ к ним осуществляется напрямую методом twisted
(аналогично d
).
ОБНОВЛЕНИЕ: В комментариях вы спрашиваете о переименовании геттеров / сеттеров.Вот еще более сложный пример.Геттеры / сеттеры вычисляют значение на основе двух полей одновременно:
class Foo {
private[this] var first: Char = _
private[this] var rest: String = _
def fake = first + rest
def fake_=(s: String) {
first = s.head
rest = s.tail
}
}
выглядит сложным внутри, но снаружи это выглядит как старое доброе свойство:
val foo = new Foo()
foo.fake = "ABC"
println(foo.fake)
Простокак если бы это было:
class Foo(var fake: String)