Java-классы содержат два совершенно разных типа членов - члены экземпляра (например, BigDecimal.plus
) и статические члены (например, BigDecimal.valueOf
). В Scala есть только членов экземпляра. Это на самом деле упрощение! Но это оставляет проблему: куда мы помещаем методы типа valueOf
? Вот где полезны объекты.
class BigDecimal(value: String) {
def plus(that: BigDecimal): BigDecimal = // ...
}
object BigDecimal {
def valueOf(i: Int): BigDecimal = // ...
}
Вы можете рассматривать это как объявление анонимного класса и его единственное создание:
class BigDecimal$object {
def valueOf(i: Int): BigDecimal = // ...
}
lazy val BigDecimal = new BigDecimal$object
При чтении кода Scala важно различать типы и значения. Я настроил IntelliJ для подсветки синего цвета.
val ls = List.empty[Int] // List is a value, a reference the the object List
ls: List[Int] // List is a type, a reference to class List
У Java также есть другая степень сложности, которая была удалена в Scala - различие между полями и методами. Поля не допускаются на интерфейсах, кроме случаев, когда они являются статическими и конечными; методы могут быть переопределены, поля вместо этого скрыты, если переопределены в подклассе. Scala устраняет эту сложность и предоставляет методы только программисту.
Наконец, быстрый ответ на ваш второй вопрос: если вы не объявляете какие-либо объекты, ваша программа может никогда не запуститься, так как для определения эквивалента public static void main(String... args) {}
в Scala вам нужен хотя бы один объект!