Часто бывает удобно иметь определения, доступные для всего пакета,
когда не нужно придумывать имя для оболочки object, которая их содержит.
Scala 2 предоставляет объекты пакета (package objects) в виде удобного контейнера, общего для всего пакета.
Объекты пакета могут содержать произвольные виды выражений, а не только переменные и методы. Например, они часто используются для хранения псевдонимов типа и наборов неявных преобразований доступных всему пакету. Объекты пакета могут также наследоваться от классов и трейтов Scala.
В будущей версии Scala 3 объекты пакета будут удалены в пользу определений верхнего уровня.
По соглашению, исходный код объекта пакета обычно помещается в файл под названием package.scala.
Каждому пакету разрешено иметь один объект пакета. Любые выражения, содержащиеся в объекте пакета, считаются членами самого пакета.
В Scala 3 любое определение может быть объявлено на верхнем уровне пакета. Например, классы, перечисления, методы и переменные.
Любые определения, размещенные на верхнем уровне пакета, считаются членами самого пакета.
В Scala 2 верхнеуровневый метод, определения типов и переменных должны были быть заключены в объект пакета. Их все еще можно использовать в Scala 3 для обратной совместимости. Вы можете увидеть, как они работают, переключая вкладки.
См. пример ниже. Предположим, есть старший класс Fruit и три наследуемых от него объекта Fruit в пакете.
gardening.fruits:
// в файле gardening/fruits/Fruit.scala
package gardening.fruits
case class Fruit(name: String, color: String)
object Apple extends Fruit("Apple", "green")
object Plum extends Fruit("Plum", "blue")
object Banana extends Fruit("Banana", "yellow")
Теперь предположим, что мы хотим поместить переменную planted и метод showFruit непосредственно в пакет gardening.
Вот как это делается:
// в файле gardening/fruits/package.scala
package gardening
package object fruits {
  val planted = List(Apple, Plum, Banana)
  def showFruit(fruit: Fruit): Unit = {
    println(s"${fruit.name}s are ${fruit.color}")
  }
}
// в файле gardening/fruits/package.scala
package gardening.fruits
val planted = List(Apple, Plum, Banana)
def showFruit(fruit: Fruit): Unit =
  println(s"${fruit.name}s are ${fruit.color}")
Для примера, следующий объект PrintPlanted импортирует planted и showFruit точно так же, как с вариантом импорта класса Fruit,
используя групповой стиль импорта пакета gardening.fruits:
// в файле PrintPlanted.scala
import gardening.fruits._
object PrintPlanted {
  def main(args: Array[String]): Unit = {
    for (fruit <- planted) {
      showFruit(fruit)
    }
  }
}
// в файле PrintPlanted.scala
import gardening.fruits.*
@main def printPlanted(): Unit =
  for fruit <- planted do
    showFruit(fruit)
Объединение нескольких определений на уровне пакета
Часто в вашем проекте может быть несколько повторно используемых определений, заданных в различных модулях, которые вы хотите агрегировать на верхнем уровне пакета.
Например, некоторые вспомогательные методы в трейте FruitHelpers
и некоторые псевдонимы терминов/типов в свойстве FruitAliases.
Вот как вы можете разместить все их определения на уровне пакета fruit:
Объекты пакета ведут себя также, как и любые другие объекты. Это означает, что вы можете использовать наследование, при этом сразу нескольких трейтов:
package gardening
// `fruits` наследует свои элементы от родителей.
package object fruits extends FruitAliases with FruitHelpers
В Scala 3 предпочтительно использовать export для объединения членов из нескольких объектов в единую область видимости.
Здесь мы определяем приватные объекты, которые смешиваются с вспомогательными трейтами,
а затем экспортируют их элементы на верхнем уровне:
package gardening.fruits
private object FruitAliases extends FruitAliases
private object FruitHelpers extends FruitHelpers
export FruitHelpers.*, FruitAliases.*
Contributors to this page:
Contents
- Введение
 - Основы
 - Единобразие типов
 - Классы
 - Значения Параметров По умолчанию
 - Именованные Аргументы
 - Трейты
 - Кортежи
 - Композиция классов с трейтами
 - Функции Высшего Порядка
 - Вложенные Методы
 - Множественные списки параметров (Каррирование)
 - Классы Образцы
 - Сопоставление с примером
 - Объекты Одиночки
 - Регулярные Выражения
 - Объект Экстрактор
 - Сложные for-выражения
 - Обобщенные Классы
 - Вариантность
 - Верхнее Ограничение Типа
 - Нижнее Ограничение Типа
 - Внутренние классы
 - Члены Абстрактного Типа
 - Составные Типы
 - Самоописываемые типы
 - Контекстные параметры, также известные, как неявные параметры
 - Неявные Преобразования
 - Полиморфные методы
 - Выведение Типа
 - Операторы
 - Вызов по имени
 - Аннотации
 - Пакеты и Импорт
 - Объекты Пакета