Pregunta

¿Hay un caso en el que se necesita un objeto complementario (singleton) para una clase? ¿Por qué querría crear una clase, decir Foo y también crear un objeto complementario para ella?

¿Fue útil?

Solución

El objeto complementario básicamente proporciona un lugar donde se puede colocar " estática-como " metodos Además, un objeto complementario, o un módulo complementario, tiene acceso completo a los miembros de la clase, incluidos los privados.

Los objetos complementarios

son excelentes para encapsular cosas como los métodos de fábrica. En lugar de tener que tener, por ejemplo, Foo y FooFactory en todas partes, puede hacer que una clase con un objeto complementario asuma las responsabilidades de fábrica.

Otros consejos

Los objetos complementarios son útiles para almacenar el estado y los métodos que son comunes a todas las instancias de una clase pero no usan métodos o campos estáticos . Usan métodos virtuales regulares que pueden ser anulados a través de la herencia. Scala realmente no tiene nada estático. Hay muchas maneras de usar esto, pero aquí hay un ejemplo simple.

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
}

Que produce esta salida:

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

... y es un buen lugar para almacenar métodos estáticos de fábrica (no ese DP) para clases acompañadas. Si asigna un nombre a los métodos de fábrica sobrecargados (/ ... /) podrá crear / inicializar su clase

  1. sin 'nuevo' (no es realmente tan importante)

  2. con diferentes conjuntos posibles de parámetros (compáralo con lo que escribe Bloch en Effective Java sobre el constructor de telescopios)

  3. con la capacidad de decidir qué clase derivada desea crear en lugar del resumen (acompañado)

Código de ejemplo:

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

No llamaría a la clase objeto / base AbstractXxxxx porque no se ve mal: como crear algo abstracto. Dale a esos nombres un significado real. Considere el uso de inmutable, método menos, clases de casos y selle la clase base abstracta.

Además de las cosas que Saem dijo en en su respuesta , el compilador Scala también busca conversiones implícitas de los tipos en los objetos complementarios correspondientes (del origen o del destino), por lo que no es necesario importar las conversiones.

Sobre el motivo de los objetos singleton en general Programación en Scala dice:

  

Como se mencionó en el Capítulo 1, una forma en que Scala está más orientada a objetos que Java es que las clases en Scala no pueden tener miembros estáticos. En su lugar, Scala tiene objetos singleton (p. 65).

Siempre veo los objetos complementarios como bridge para escribir tanto código funcional como orientado a objetos en Scala. Muchas veces solo necesitamos funciones puras que toman alguna entrada y proporcionan un resultado de procesamiento. Poner esas funciones relevantes en el objeto complementario hace que sea fácil de buscar y usar, tanto para mí como para alguien que se construye sobre mi código.

Además, es una característica proporcionada por el lenguaje para escribir el patrón de singleton sin hacer nada. Esto es especialmente útil cuando necesita un singleton para encapsular un delegador para la vida de JVM. Por ejemplo, al escribir una biblioteca de cliente HTTP simple en Scala donde puede encapsular un delegador basado en la implementación de Java subyacente y permitir que los consumidores de su API vivan en un mundo puro.

Si define la clase y el objeto en el mismo archivo con el mismo nombre, se conocen como clase y objeto complementarios. Scala no tiene estática como palabra clave de JAVA, puede tomar como reemplazo de la estática con la clase complementaria y el objeto en Scala.

Para obtener más información detallada, consulte el artículo palabra clave de clase y objeto en la programación de Scala

Al principio, proporciona una clara separación de métodos estáticos y métodos no estáticos. También proporciona una forma sencilla de crear una clase singleton.

También puede heredar métodos de otras clases y / o rasgos, lo que no se puede hacer con los métodos estáticos de Java, y se puede pasar como un parámetro.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top