Есть ли случай, когда нужен сопутствующий объект (синглтон) для класса? Зачем мне, скажем, создавать класс, Foo
а также создавать для него сопутствующий объект?
oop
scala
companion-object
Рахул
источник
источник
Ответы:
Сопутствующий объект в основном предоставляет место, где можно разместить «статические» методы. Более того, сопутствующий объект или сопутствующий модуль имеет полный доступ к членам класса, включая частные.
Объекты-компаньоны отлично подходят для инкапсуляции таких вещей, как фабричные методы. Вместо того, чтобы иметь, например,
Foo
иFooFactory
везде, вы можете иметь класс с объектом компаньона взять на фабричной обязанности.источник
Сопутствующие объекты полезны для хранения состояния и методов, общих для всех экземпляров класса, но они не используют статические методы или поля. Они используют обычные виртуальные методы, которые можно переопределить посредством наследования. В Scala действительно нет ничего статичного. Есть много способов использовать это, но вот простой пример.
Что производит этот вывод:
источник
... и это хорошее место для хранения статических фабричных методов (не DP) для сопровождаемых классов. Если вы назовете эти перегруженные фабричные методы apply (/ ... /), вы сможете создать / инициализировать свой класс
без "нового" (не так уж и важно)
с различными возможными наборами параметров (сравните с тем, что Блох пишет в Effective Java о телескопическом конструкторе)
с возможностью решать, какой производный класс вы хотите создать вместо абстрактного (сопровождаемого)
Пример кода:
Я бы не стал называть объект / базовый класс AbstractXxxxx, потому что он неплохо выглядит: вроде создания чего-то абстрактного. Придайте этим именам реальный смысл. Рассмотрите возможность использования неизменяемых, безметодных, case-классов и запечатайте абстрактный базовый класс.
источник
RealThing
иAlternativeThing
класс должен иметьprivate
конструктор, чтобы заставить пользователя использоватьAbstractClass
фабрику has.class AlternativeThing private(i: Int) extends AbstractClass
В дополнение к тому, что Саэм сказал в своем ответе , компилятор Scala также ищет неявные преобразования типов в соответствующих сопутствующих объектах (исходных или целевых), поэтому преобразования не нужно импортировать.
О причине появления одноэлементных объектов в общем программировании на Scala говорится:
источник
Я всегда рассматриваю сопутствующие объекты как мост для написания как функционального, так и объектно-ориентированного кода на Scala. Часто нам просто нужны чистые функции, которые принимают некоторый ввод и предоставляют результат обработки. Помещение этих соответствующих функций в сопутствующий объект упрощает поиск и использование для меня, а также для кого-то, построенного поверх моего кода.
Более того, это языковая функция для написания одноэлементного шаблона без каких-либо действий. Это особенно полезно, когда вам нужен синглтон для инкапсуляции делегатора на время существования JVM. Например, написание простой клиентской библиотеки HTTP на Scala, в которой вы можете инкапсулировать базовый делегатор на основе реализации Java и позволить потребителям вашего API жить в чистом мире.
источник
Если вы определяете класс и объект в одном файле с тем же именем, они называются сопутствующим классом и объектом. В Scala нет static в качестве ключевого слова JAVA. Вы можете заменить static на класс-компаньон и объект в Scala.
Для получения более подробной информации, пожалуйста, проверьте класс статьи и ключевое слово объекта в программировании на Scala.
источник
Во-первых, он обеспечивает четкое разделение статических и нестатических методов методов, а также предоставляет простой способ создания одноэлементного класса.
Он также может наследовать методы от других классов и / или признаков, что невозможно сделать с помощью статических методов Java. Его можно передать как параметр.
источник