Каково обоснование наличия сопутствующих объектов в Scala?



есть ли случай, когда требуется сопутствующий объект (синглтон) для класса? Зачем мне создавать класс, скажем Foo, а также создать объект-спутник для него?

557   7  

7 ответов:

сопутствующий объект в основном предоставляет место, где можно поместить "статические" методы. Кроме того, сопутствующий объект или сопутствующий модуль имеет полный доступ к членам класса, в том числе частным.

сопутствующие объекты отлично подходят для инкапсуляции таких вещей, как заводские методы. Вместо того, чтобы иметь, например,Foo и FooFactory везде, вы можете иметь класс с сопутствующим объектом взять на себя заводские обязанности.

сопутствующие объекты полезны для хранения состояния и методов, которые являются общими для всех экземпляров класса но они не используют статический методы или поля. Они используют обычные виртуальные методы, которые могут быть переопределены через наследование. У 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

...и это хорошее место для хранения статических заводских методов (не то, что DP) для сопровождаемых классов. Если вы называете эти перегруженные заводские методы применяются (/.../) вы сможете создать/инициализировать класс

  1. без ' new '(не очень важно)

  2. с различными возможными наборами параметров (сравните с тем, что блох пишет в эффективной Java о телескопическом конструкторе)

  3. С возможность решить, какой производный класс вы хотите создать вместо абстрактного (сопровождаемого) одного

пример кода:

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, потому что это не выглядит плохо: как создание чего-то абстрактного. Дайте этим именам реальный смысл. Рассмотрите возможность использования неизменяемых классов case, method less и запечатайте абстрактный базовый класс.

в дополнение к тому, что Саем сказал в ответ компилятор Scala также ищет неявные преобразования типов в соответствующих сопутствующих объектах (либо источника, либо цели), поэтому преобразования не нужно импортировать.

о причине одноэлементных объектов в целом программирование в Scala говорит:

Как упоминалось в Главе 1, Один из способов, в котором Scala является более объектно-ориентированным, чем Java - это то, что классы в Scala не могут иметь статических членов. Вместо этого Scala имеет одноэлементные объекты (стр. 65).

Я всегда вижу сопутствующие объекты как мост для написания функционального и объектно-ориентированного кода в Scala. Много раз нам просто нужны чистые функции, которые принимают некоторые входные данные и обеспечивают результат обработки. Размещение этих соответствующих функций в сопутствующем объекте упрощает поиск и использование, как для меня, так и для какого-то одного здания поверх моего кода.

кроме того, это языковая функция, предоставляемая для написания одноэлементного шаблона, ничего не делая. Это особенно полезно, когда вам нужен синглтон для инкапсуляции делегатора для жизни JVM. Например, написание простой клиентской библиотеки HTTP в Scala, где вы можете инкапсулировать базовый делегатор на основе реализации Java и позволить потребителям вашего API жить в чистом мире.

Если вы определяете класс и объект в одном файле с одинаковым именем, они известны как сопутствующий класс и объект. Scala не имеет статического ключевого слова JAVA, вы можете взять в качестве замены статического класса и объекта companion в Scala.

для получения более подробной информации, пожалуйста, проверьте статью ключевое слово класса и объекта в программировании scala

во-первых, он обеспечивает четкое разделение статических и нестатических методов методов.Также предоставляется простой способ создания одноэлементного класса.

Он также может наследовать методы от других классов и / или признаков, которые не могут быть выполнены с помощью статических методов Java.и может быть передан в качестве параметра.

Comments

    Ничего не найдено.