Каково обоснование наличия сопутствующих объектов в Scala?
Есть ли случай, когда необходим объект-компаньон (singleton) для класса? Почему я хочу создать класс, скажем Foo
, а также создать для него объект-компаньон?
Ответы
Ответ 1
Сопутствующий объект в основном обеспечивает место, где можно ставить "статические" методы. Кроме того, объект-компаньон или сопутствующий модуль имеют полный доступ к членам класса, включая частные.
Объекты Companion отлично подходят для инкапсуляции таких вещей, как factory. Вместо того чтобы иметь везде, где есть Foo
и FooFactory
, вы можете иметь класс со своим сопутствующим объектом для выполнения обязанностей factory.
Ответ 2
Объекты Companion полезны для хранения состояния и методов, которые являются общими для всех экземпляров класса , но они не используют методы или поля static. Они используют обычные виртуальные методы, которые могут быть переопределены через наследование. Scala действительно не имеет ничего статического. Существует множество способов использования этого, но здесь простой пример.
abstract class AnimalCounter
{
var animals = 0
def name: String
def count()
{
animals += 1
println("%d %ss created so far".format(animals, name))
}
}
abstract class Animal
{
def companion: AnimalCounter
companion.count()
}
object Dog extends AnimalCounter
{
val name = "dog"
}
class Dog extends Animal
{
def companion = Dog
}
object Cat extends AnimalCounter
{
val name = "cat"
}
class Cat extends Animal
{
def companion = Cat
}
Что производит этот вывод:
scala> new Dog
1 dogs created so far
scala> new Cat
1 cats created so far
scala> new Dog
2 dogs created so far
scala> new Cat
2 cats created so far
Ответ 3
... и это хорошее место для хранения статических factory методов (не для DP) для сопровождающих классов. Если вы назовете эти перегруженные методы factory apply (/.../), вы сможете создать/инициализировать класс
-
без "нового" (не так уж и важно)
-
с различными возможными наборами параметров (по сравнению с тем, что Блох пишет в Effective Java о конструкторе телескопа)
-
с возможностью решить, какой производный класс вы хотите создать вместо абстрактного (сопровождаемого).
Пример кода:
abstract class AbstractClass;
class RealThing(s: String) extends AbstractClass;
class AlternativeThing(i: Int) extends AbstractClass;
object AbstractClass {
def apply(s: String) = {
new RealThing(s)
}
def apply(i: Int) = {
new AlternativeThing(i)
}
}
// somewhere else you can
val vs = AbstractClass("asdf") // gives you the RealThing wrapped over string
val vi = AbstractClass(123) // gives you AlternativeThing wrapped over int
Я бы не назвал объект/базовый класс AbstractXxxxx, потому что он выглядит плохо: вроде создания чего-то абстрактного. Дайте этим именам реальный смысл.
Подумайте об использовании неизменяемых классов, методов менее, классов и запечатайте абстрактный базовый класс.
Ответ 4
В дополнение к тем, что Saem сказал в его ответе, компилятор Scala также ищет неявные преобразования типов в соответствующих сопутствующих объектах (источника или цели), поэтому конверсии не нужно импортировать.
О причине одиночных объектов вообще Программирование в Scala говорит:
Как упоминалось в главе 1, один из способов, в котором Scala более объектно-ориентирован, чем Java, состоит в том, что классы в Scala не могут иметь статические элементы. Вместо этого Scala имеет одноэлементные объекты (стр. 65).
Ответ 5
Я всегда вижу сопутствующие объекты в качестве моста для написания функционального и объектно-ориентированного кода в Scala. Много раз нам нужны только чистые функции, которые вносят определенный вклад и обеспечивают результат обработки. Помещение этих соответствующих функций в объект-компаньон позволяет легко искать и использовать для себя, а также для одного здания поверх моего кода.
Кроме того, это функция, предоставляющая язык для написания одноэлементного шаблона без каких-либо действий. Это особенно полезно, когда вам нужен синглтон, чтобы инкапсулировать делегата на всю жизнь JVM. Например, написав простую HTTP-клиентскую библиотеку в Scala, где вы можете инкапсулировать основанного на Java разработчика на основе реализации и позволить потребителям вашего API жить в чистом мире.
Ответ 6
Если вы определяете класс и объект в одном файле с тем же именем, они называются сопутствующим классом и объектом. Scala не имеют статического слова как JAVA, вы можете взять в качестве замены статический класс и объект-компаньон в Scala.
Для получения более подробной информации, пожалуйста, проверьте статью
ключевое слово class и object в Scala программировании
Ответ 7
Сначала он обеспечивает четкое разделение статических и нестационарных методов методов. Также обеспечиваем простой способ создания класса singleton.
Он также может наследовать методы других классов и/или признаков, которые не могут быть выполнены с помощью Java static methods.and может быть передан как параметр.