В Scala ключевое слово object
создает объект Singleton (паттерн проектирования “Одиночка”). Другими словами, объект определяет класс, который имеет только один экземпляр.
Объекты имеют несколько применений:
- Они используются для создания коллекций служебных методов.
- Сопутствующий объект — это объект с тем же именем, что и у класса, определенного в этом же файле. В этой ситуации такой класс также называется сопутствующим классом.
- Они используются для реализации трейтов для создания модулей.
“Полезные” методы
Поскольку object
является “одиночкой”, к его методам можно обращаться так же, как к статичным методам в Java классе. Например, этот объект StringUtils
содержит небольшой набор методов, связанных со строками:
object StringUtils { def isNullOrEmpty(s: String): Boolean = s == null || s.trim.isEmpty def leftTrim(s: String): String = s.replaceAll("^\\s+", "") def rightTrim(s: String): String = s.replaceAll("\\s+$", "") }
object StringUtils: def isNullOrEmpty(s: String): Boolean = s == null || s.trim.isEmpty def leftTrim(s: String): String = s.replaceAll("^\\s+", "") def rightTrim(s: String): String = s.replaceAll("\\s+$", "")
Поскольку StringUtils
- это “одиночка”, его методы можно вызывать непосредственно для объекта:
val x = StringUtils.isNullOrEmpty("") // true val x = StringUtils.isNullOrEmpty("a") // false
Сопутствующие объекты
Сопутствующие класс или объект могут получить доступ к закрытым членам своего компаньона. Используйте сопутствующий объект для методов и значений, которые не относятся к экземплярам сопутствующего класса.
В этом примере показано, как метод area
в сопутствующем классе может получить доступ к приватному методу calculateArea
в своем сопутствующем объекте:
import scala.math._ 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 circle1 = new Circle(5.0) circle1.area // Double = 78.53981633974483
import scala.math.* 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 circle1 = Circle(5.0) circle1.area // Double = 78.53981633974483
Создание модулей из трейтов
Объекты также можно использовать для реализации трейтов для создания модулей. Эта техника берет две трейта и объединяет их для создания конкретного object
-а:
trait AddService { def add(a: Int, b: Int) = a + b } trait MultiplyService { def multiply(a: Int, b: Int) = a * b } // реализация трейтов выше в качестве конкретного объекта object MathService extends AddService with MultiplyService // использование объекта import MathService._ println(add(1,1)) // 2 println(multiply(2,2)) // 4
trait AddService: def add(a: Int, b: Int) = a + b trait MultiplyService: def multiply(a: Int, b: Int) = a * b // реализация трейтов выше в качестве конкретного объекта object MathService extends AddService, MultiplyService // использование объекта import MathService.* println(add(1,1)) // 2 println(multiply(2,2)) // 4