Costruttore privato e protetto in Scala


109

Sono stato curioso dell'impatto di non avere un costruttore primario esplicito in Scala, solo il contenuto del corpo della classe.

In particolare, sospetto che il pattern del costruttore privato o protetto, ovvero il controllo della costruzione tramite l'oggetto associato o un'altra classe o metodi dell'oggetto, potrebbe non avere un'implementazione ovvia.

Ho sbagliato? In caso affermativo, come si fa?


Potresti avere un singleton di Scala (con la parola chiave object, cioè), e definire la tua classe come privata all'interno di quel singleton e avere metodi del singleton per costruire i tuoi oggetti.
Paggas

@Paggas, sfortunatamente quando restituisci un'istanza di una classe contrassegnata come privata al di fuori del suo ambito, non verrà compilata, anche se restituita da un metodo dell'oggetto associato nell'ambito.
Don Mackenzie,

Questo viene fatto abbastanza abbondantemente in tutto il codice sorgente di Scalaz. Il concetto è noto anche come tipo di dati algebrico astratto .
Tony Morris

Risposte:


190

È possibile dichiarare il costruttore predefinito come privato / protetto inserendo la parola chiave appropriata tra il nome della classe e l'elenco dei parametri, in questo modo:

class Foo private () { 
  /* class body goes here... */
}

Grazie Aleksander, puoi dirmi per favore se questo è presentato in uno dei libri in scala o nella specifica del linguaggio? Scusa, non posso ancora votare.
Don Mackenzie,

Ho appena dato un'occhiata alla spiegazione dei costruttori di "Programming Scala" (pagine 92-95) e non la vedo menzionata lì. In realtà ho trovato la risposta alla tua domanda in un vecchio log delle modifiche, ma non l'ho mai visto menzionato da nessun'altra parte prima. Link: scala-lang.org/node/43#2.4.0
Aleksander Kmetec

18
Pag 414 di "Programmare in Scala". Pagina 97 della Scala di programmazione di Wampler. Pagina 60 della Scala di programmazione di Subramaniam. Non ho un PDF di Beginning Scala con me in questo momento per verificarlo.
Daniel C. Sobral,

Oh, ora lo vedo a pagina 97. Grazie.
Aleksander Kmetec

1
Grazie ad entrambi per le ulteriori ricerche, ho il libro di Wampler, ma solo sul telefono e chiaramente non l'ho letto a fondo, ma ho scoperto che si integra sorprendentemente bene con il libro di Odersky.
Don Mackenzie,

64

La risposta di Aleksander è corretta, ma Programming in Scala offre un'ulteriore alternativa:

sealed trait Foo {
 // interface
}

object Foo {
  def apply(...): Foo = // public constructor

  private class FooImpl(...) extends Foo { ... } // real class
}

18
Popping anni dopo per dire: penso che questa sia una buona risposta alla domanda ma una cattiva soluzione al problema. Se qualche futuro programmatore usasse il codice di Aleksander, direbbe "Ah, il costruttore principale è privato ma gli altri no." Se quel programmatore guardasse il codice di Daniel, direbbe: "Ah, stanno usando un pattern Factory per compensare l'incapacità di Scala di contrassegnare i costruttori predefiniti come privati. Aspetta, Scala può contrassegnare i costruttori predefiniti come privati! Cosa sta succedendo qui?!?" In altre parole, un cattivo rapporto WTF / LOC.
Malvolio

20
@Malvolio non sono del tutto d'accordo. Questo modello non solo rende privato il costruttore principale, ma anche l' implementazione , costringendo l'utente a utilizzare l'interfaccia (tratto). Questo ha il suo valore. Quanto a qualcuno che pensa qualcosa perché non conosce la lingua - piffle! Per citare Kenny Tilton, impara quella dannata lingua !
Daniel C. Sobral,

7
Va detto da qualche parte che questo approccio significa non utilizzare la newparola chiave.
Travis Parks

1
Un avvertimento con questo approccio è che qualcuno potrebbe ancora istanziare un Foo attraverso la propria implementazione. Ciò potrebbe essere visto come un vantaggio o uno svantaggio a seconda del motivo per il controllo della costruzione.
aij

1
@aij True, quindi l'ho fatto in modo che non potesse più accadere. :)
Daniel C. Sobral
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.