2011-01-31 19 views
12

Come si può tradurre il seguente codice Java in Scala?Le migliori variabili di istanza di Scala

class ClassA { 
    private int field1; 
    private int field2; 

    public ClassA() { 
     field1 = 1; 
     field2 = 2; 
    } 
} 

posso vedere due opzioni:

class ClassA(val field1: Int, val field2: Int) { 
    .... 
} 

O

class ClassA { 
    val field1: Int = 1 
    val field2: Int = 2 
} 

ciò che è raccomandato, e perché?

+0

Nessuna versione è equivalente, poiché entrambi i campi sono privati ​​nella versione Java e pubblici nelle alternative Scala che hai mostrato. Forse ti piacerebbe essere più specifico su ciò che vuoi ottenere? –

risposta

4

Se si desidera disporre di campi privati, perché non dichiararli privati?

class ClassA { 
    private val field1: Int = 1 
    private val field2: Int = 2 
} 
5

La più grande differenza tra i due è che il parametro di classe uno può essere utilizzato come costruttore. Se vuoi che il costruttore non abbia parametri, come il tuo esempio Java, allora devi usare il secondo, aggiungendo il modificatore privato come suggerito da @Debilski.

Un'altra opzione sarebbe utilizzare i parametri predefiniti nel costruttore. In questo modo i campi possono essere modificati se necessario:

class ClassA (private val field1: Int = 1, private val field2: Int = 2) 

// Using defaults 
val a = new ClassA 

// Setting new values 
val b = new ClassA(3, 4) 
+0

Questa è una bella soluzione, ma non è equivalente al codice Java dell'OP. – Raphael

+0

@Raphael Questo è vero. Ma dato che l'esempio di Java dato sembra piuttosto inutile in sé, ho pensato che forse mostrare alcune opzioni potrebbe essere interessante :) – eivindw

1

Se sempre vuole che campo1 e campo2 hanno lo stesso valore per ogni istanza della classe A, vorrei suggerire di metterli in un modulo compagna:

object A { 
    private val field1 = 1 
    private val field2 = 2 
} 

e poi li usano in classe a:

class A { 
    def complexInternalComputation = 2*A.a 
} 

o in questo modo:

class A { 
    import A._ 
    def complexInternalComputation = 2*a 
} 
+0

Questo non funziona; 'A.a' non è accessibile da un'istanza di classe' A' poiché è privata. – Raphael

+0

Dalla specifica scala, §5.2: • Il modificatore privato può essere utilizzato con qualsiasi definizione o dichiarazione in un modello. È possibile accedere a tali membri solo dal modello che lo racchiude direttamente e dal suo modulo compagno o classe compagno (§5.4). – Nicolas

+0

Tuttavia, fallisce in REPL ma funziona in un file. – Nicolas

16

Non c'è semplice traduzione da Java a Scala, dipende dal contesto:

  • sono le variabili mutabili in Java? Se sì (altrimenti dovrebbero essere definitivi in ​​Java): avrebbe senso renderli immutabili in Scala?
  • Il costruttore dovrebbe rimanere pubblico in Scala? Sarebbe una fabbrica (ad esempio un metodo apply in l'oggetto companion) più appropriato?
  • Perché sono le variabili private? Hanno getter e/o setter?
  • Quando sono necessarie le variabili, avrebbe senso renderle pigre?
  • Se i valori sono immutabili ed esposti, sarebbero utili nella corrispondenza dei modelli? Una case class sarebbe la scelta giusta?
  • Le variabili possono essere raggruppate (ad esempio in una tupla) al fine di semplificare API e accesso?

Vedete, ci sono così tante considerazioni. Suggerirei di conoscere le possibilità di Scala e di giocare con approcci diversi, altrimenti rimarrai bloccato nella trappola "Scala come migliore Java" più a lungo del necessario.

8

Questa è la traduzione più diretta per Scala:

class ClassA{ 
    private var field1 = 1 
    private var field2 = 2 
} 

nota l'utilizzo di var invece di val. val è un campo immutabile, corrispondente a public final in Java. Pertanto non può essere modificato in seguito e fornire un modo per inizializzare un campo di questo tipo sul valore corretto per una determinata istanza è importante.

Per decidere cosa si desidera utilizzare è necessario porsi le domande elencate nella risposta di Landei.

+0

Non proprio la traduzione diretta - Le variabili private Java sono private di classe, non private di istanza, quindi dovresti lasciar cadere [this]. – Submonoid

+0

@Submonoid Grazie. Sembra che abbia sempre sbagliato. :) – ziggystar

Problemi correlati