Scala 3 — Book

Одноэлементные объекты

Language

В 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 

Contributors to this page: