scalabook
Сопутствующие объекты
Объект, который имеет то же имя, что и класс, и объявлен в том же файле, что и класс, называется "сопутствующим объектом" (companion object). Аналогично, соответствующий класс называется сопутствующим классом объекта (companion class). Сопутствующий класс или объект может получить доступ к закрытым членам своего "соседа".
Сопутствующие объекты используются для методов и значений, которые не являются специфичными для экземпляров сопутствующего класса.
В следующем примере класс Circle
содержит метод с именем area
, который специфичен для каждого экземпляра.
А его сопутствующий объект содержит метод с именем calculateArea
,
который (а) не специфичен для экземпляра и (б) доступен для каждого экземпляра:
import scala.math.*case class Circle(radius: Double): import Circle.* def area: Double = calculateArea(radius)object Circle: private def calculateArea(radius: Double): Double = Pi * pow(radius, 2.0)val circle = Circle(5.0)circle.area// res0: Double = 78.53981633974483
В этом примере метод area
, доступный для каждого экземпляра Circle
, использует метод calculateArea
,
определенный в сопутствующем объекте.
Кроме того, поскольку calculateArea
является закрытым, к нему нельзя получить доступ с помощью другого кода,
но, как показано, его могут видеть экземпляры класса Circle
.
Другие виды использования сопутствующих объектов
Сопутствующие объекты могут использоваться для нескольких целей:
- их можно использовать для группировки "статических" методов в пространстве имен, как в примере выше
- эти методы могут быть
public
илиprivate
- если бы
calculateArea
былpublic
, к нему можно было бы получить доступ из любого места какCircle.calculateArea
- эти методы могут быть
- они могут содержать методы
apply
, которые — благодаря некоторому синтаксическому сахару — работают как фабричные методы для создания новых экземпляров - они могут содержать методы
unapply
, которые используются для деконструкции объектов, например, с помощью pattern matching
Вот краткий обзор того, как методы apply
можно использовать в качестве фабричных методов для создания новых объектов:
class Person: var name = "" var age = 0 override def toString = s"$name is $age years old"
object Person: def apply(name: String): Person = // одноаргументный фабричный метод val p = new Person p.name = name p
def apply(name: String, age: Int): Person = // двуаргументный фабричный метод val p = new Person p.name = name p.age = age pend Person
val joe = Person("Joe")// joe: Person = Joe is 0 years oldval fred = Person("Fred", 29)// fred: Person = Fred is 29 years old
Ссылки: