2010-04-18 2 views
18

Basta chiedersi se è possibile. Quello che vorrei veramente fare è controllare e possibilmente modificare uno degli argomenti prima che venga memorizzato come val.Scala: è possibile sovrascrivere il costruttore di case case predefinito?

In alternativa, potrei utilizzare un sovraccarico e rendere privato il costruttore predefinito. In tal caso, vorrei anche rendere privato il costruttore factory predefinito nell'oggetto companion, come dovrei farlo?

Molte grazie.

Adam

edit: bene ho capito che per fare il privato costruttore di default rende anche la fabbrica di default costruttore privato, quindi ho una soluzione, io sono ancora interessato a sapere se il costruttore di default è superabile se

+3

Perché vuoi farlo? Una classe case deve essere utilizzata per definire i tipi di dati algebrici, quindi un costruttore aggiunto che altera gli argomenti del chiamante è un po 'una bugia. Per quanto riguarda la validazione degli argomenti, ciò può essere fatto nel costruttore principale usando 'assert' o' require'. –

+0

@ adam77 Per riformulare l'istruzione iniziale come una domanda, "Posso controllare ed eventualmente modificare un [parametro della classe caso]?" La risposta è si. Ho appena pubblicato i dettagli su una domanda correlata che si trova qui: http://stackoverflow.com/a/25538287/501113 – chaotic3quilibrium

risposta

11

La presenza di costruttori di case case secondarie non obbliga il compilatore a produrre metodi di produzione aggiuntivi nel compagno della classe, quindi non sarà possibile ottenere la comodità di CaseClaseName(«secondary constructor parameter list»>) per crearli. Dovrai utilizzare la parola chiave new.

È meglio inserire il tipo di logica che si sta descrivendo in metodi di fabbrica alternativi nell'oggetto associato e attenersi all'utilizzo del costruttore principale.

3

È possibile sovraccaricare i costruttori. È lo stesso di C++ o Java. Basta fare un altro costruttore.

class Foo(_input:Int){ 
    def this() = this(0) 
} 

Oppure è possibile vedere this messaggio SO.

+1

Grazie, ma la domanda è override non sovraccarico. – adam77

+8

Nessun costruttore può essere sovrascritto, poiché non viene ereditato per cominciare. –

1

È possibile trasformare una classe normale in una classe pseudo-case scrivendo i propri metodi apply (per la fabbrica) e unapply (per la corrispondenza del modello) nell'oggetto associato. Oppure, potresti semplicemente scrivere un metodo factory con nome nell'oggetto companion della classe case.

22

Non è possibile modificare il modo in cui il costruttore predefinito memorizza i propri parametri (ad esempio modificando i parametri prima che vengano memorizzati come val s) ma si ha l'opzione di generare un'eccezione se i parametri sono errati (questo si verifica dopo che i parametri vengono memorizzati)

case class Foo(x:Int){ 
    if (x<0) throw SomeException; 
} 

Hai anche la possibilità di attuare ulteriori costruttori che chiamano il primo costruttore

case class Foo(x:Int){ 
    def this(x:Int,y:Int) = this(x+y) 
} 

ma quelli non si ottiene metodi di fabbrica.

Si potrebbe facilmente creare il metodo factory per te stesso aggiungendo all'oggetto compagna

object Foo{ 
    def apply(x:Int,y:Int) = new Foo(x,y) 
} 

Tutto il resto più complicato di così, e si deve rinunciare alla classe caso e mettere in atto le sue parti da soli: apply , unapply, equals e hashCode. Programmazione in Scala parla di come eseguire tutte queste operazioni, fornendo buone formule per equals e hashCode.

+0

È possibile modificare i parametri in modo sicuro prima che siano memorizzati nella classe del caso. E puoi ancora fare alcune cose più complicate senza rinunciare a tutti i vantaggi delle case-class. Ho appena descritto la mia soluzione su un altro thread: http://stackoverflow.com/a/25538287/501113 – chaotic3quilibrium