2009-03-04 27 views
89

Esiste un caso in cui è necessario un oggetto companion (singleton) per una classe? Perché dovrei creare una classe, ad esempio Foo e anche creare un oggetto companion per esso?Qual è la logica alla base degli oggetti associati in Scala?

+3

Vedere anche http://programmers.stackexchange.com/questions/179390/what-are-the-advantages-of-scalas-companion-objects-vs-static-methods – Vadzim

+0

Vedere anche http://stackoverflow.com/a/9806136/736957 che è una buona raccolta di risposte qui – laughedelic

risposta

65

L'oggetto companion fornisce fondamentalmente un luogo in cui è possibile inserire metodi "statici". Inoltre, un oggetto companion o un modulo companion ha accesso completo ai membri della classe, inclusi quelli privati.

Gli oggetti companion sono ottimi per incapsulare cose come i metodi di fabbrica. Invece di dover, ad esempio, Foo e FooFactory ovunque, è possibile avere una classe con un oggetto companion che assuma le responsabilità di fabbrica.

18

In aggiunta alle cose che Saem ha detto in his reply, il compilatore Scala cerca anche implicit conversions di tipi negli oggetti corrispondenti corrispondenti (della sorgente o della destinazione), quindi le conversioni non devono essere importate.

circa il motivo per gli oggetti Singleton in genere Programming in Scala dice:

Come accennato 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 (pagina 65).

28

... ed è un buon posto per memorizzare i metodi statici di fabbrica (non quello DP) per le classi accompagnate. Se il nome applicano tali metodi di fabbrica di overload (/ ... /) si sarà in grado di creare/inizializzazione si class

  1. senza 'nuovo' (non è poi così importante)

  2. con diversi set possibili di parametri (confronto a quello che Bloch scrive in Effective Java su telescopico costruttore)

  3. con la possibilità di decidere quale classe derivata si desidera creare al posto del astratta (accompagnati) uno

  4. 012.

codice 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 

io non lo chiamerei l'AbstractXxxxx classe di oggetti/base, perché non sembra male: come la creazione di qualcosa di astratto. Dare a quei nomi un vero significato. Considera l'uso di classi di casi immutabili, meno metodiche e sigilla la classe base astratta.

+2

La classe 'RealThing' e' AlternativeThing' dovrebbe avere un costruttore 'private' per forzare l'utente ad usare' AbstractClass' ha factory. 'classe AlternativeThing private (i: Int) estende AbstractClass' – metch

+1

metch, si. Hai ragione. –

54

Gli oggetti companion sono utili per l'archiviazione 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 sostituiti tramite ereditarietà. Scala non ha davvero nulla di statico. Ci sono molti modi in cui puoi usarlo, 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 
+1

l'illustrazione simile può essere trovata anche qui: http://daily-scala.blogspot.sk/2009/09/companion-object.html – xhudik

3

vedo sempre guidata oggetti come ponte per scrivere sia codice funzionale e ad oggetti in Scala. Molte volte abbiamo solo bisogno di funzioni pure che prendono un input e forniscono un risultato di elaborazione. Mettere quelle funzioni rilevanti nell'oggetto compagno rende facile cercare e utilizzare, sia per me stesso che per qualcuno che costruisca il mio codice.

Inoltre, è una funzione fornita dal linguaggio per scrivere il modello singleton senza fare nulla. Ciò è particolarmente utile quando hai bisogno di 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 della propria API di vivere nel mondo puro.

0

Se si definisce la classe e l'oggetto nello stesso file con lo stesso nome, sono noti come classe e oggetto companion. Scala non ha statica come parola chiave JAVA, puoi usare la sostituzione di statica con la classe companion e l'oggetto in Scala.

Per ulteriori informazioni di dettaglio si prega di articolo class and object keyword in scala programming

0

Inizialmente, fornisce una chiara separazione di statica e metodi non statici methods.Also fornire un modo semplice per creare classe singleton.

È inoltre possibile ereditare metodi da altre classi e/o tratti, che non possono essere eseguiti con metodi statici Java e possono essere passati come parametro.