Domanda

Esiste un caso in cui è necessario un oggetto associato (singleton) per una classe? Perché dovrei voler creare una classe, dire Foo e anche creare un oggetto associato per esso?

È stato utile?

Soluzione

L'oggetto associato in sostanza fornisce un posto dove si può mettere "statico" metodi. Inoltre, un oggetto compagno o modulo compagno ha pieno accesso ai membri della classe, compresi quelli privati.

Gli oggetti associati sono ottimi per incapsulare cose come i metodi di fabbrica. Invece di dover avere, ad esempio, Foo e FooFactory ovunque, puoi fare in modo che una classe con un oggetto compagno assuma le responsabilità di fabbrica.

Altri suggerimenti

Gli oggetti associati sono utili per la memorizzazione dello stato e dei metodi comuni a tutte le istanze di una classe ma non utilizzano metodi o campi statici . Usano metodi virtuali regolari che possono essere sovrascritti tramite ereditarietà. Scala non ha veramente nulla di statico. Esistono molti modi per utilizzarlo, ma ecco un semplice esempio.

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
}

Che produce questo output:

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

... ed è un buon posto per memorizzare metodi di fabbrica statici (non quel DP) per le classi accompagnate. Se assegni questi metodi di fabbrica sovraccarichi (/ ... /) sarai in grado di creare / inizializzare la tua classe

  1. senza "nuovo" (non molto importante)

  2. con diversi possibili set di parametri (confronta con ciò che Bloch scrive in Effective Java sul costruttore del telescopio)

  3. con la possibilità di decidere quale classe derivata si desidera creare anziché quella astratta (accompagnata)

Codice di esempio:

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

Non definirei l'oggetto / la classe base AbstractXxxxx perché non sembra male: come creare qualcosa di astratto. Dai a quei nomi un significato reale. Prendi in considerazione l'uso di immutabili, metodo in meno, classi maiuscole e sigilla la classe base astratta.

Oltre a ciò che Saem ha detto in la sua risposta , il compilatore Scala cerca anche conversioni implicite dei tipi negli oggetti companion corrispondenti (della sorgente o della destinazione), quindi non è necessario importare le conversioni.

Informazioni sul motivo degli oggetti singleton in generale Programmazione in Scala dice:

  

Come menzionato nel Capitolo 1, un modo in cui Scala è più orientato agli oggetti di Java è che le classi in Scala non possono avere membri statici. Invece, Scala ha oggetti singleton (p. 65).

Vedo sempre gli oggetti companion come un bridge per scrivere sia codice funzionale che orientato agli oggetti in Scala. Molte volte abbiamo solo bisogno di funzioni pure che accettano input e forniscono un risultato di elaborazione. Mettere quelle funzioni rilevanti nell'oggetto compagno rende facile la ricerca e l'uso, per me e per qualcuno che si basa sul mio codice.

Inoltre, è una funzione fornita dalla lingua per scrivere il modello singleton senza fare nulla. Ciò è particolarmente utile quando è necessario un singleton per incapsulare un delegatore per la vita di JVM. Ad esempio, scrivendo una semplice libreria client HTTP in Scala in cui è possibile incapsulare un delegatore basato sull'implementazione Java sottostante e consentire agli utenti dell'API di vivere nel mondo puro.

Se si definiscono classe e oggetto nello stesso file con lo stesso nome, sono noti come classe e oggetto associati. Scala non ha static come parola chiave JAVA, puoi sostituirlo con static companion class e object in Scala.

Per ulteriori informazioni dettagliate, consultare l'articolo parola chiave classe e oggetto nella programmazione scala

Inizialmente fornisce una chiara separazione dei metodi statici e non statici. Fornisce inoltre un modo semplice per creare una classe singleton.

Può anche ereditare metodi da altre classi e / o tratti, che non possono essere eseguiti con metodi statici Java e possono essere passati come parametro.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top