2011-06-16 11 views
12

mayoría de las veces, un constructor para una clase no hace más que tomar sus valores de argumento y los utilizan para establecer las variables de instancia:La implementación de un único constructor de Scala que hace más que las variables de ajuste

// Java 
public class MyClass { 
    private int id; 

    public MyClass(int id) { 
     this.id = id; 
    } 
} 

Así que entiendo la eficiencia de la sintaxis constructor por defecto de Scala ... simplemente declarando una lista de variables entre paréntesis al lado del nombre de la clase:

// Scala 
class MyClass(id: int) { 
} 

Sin embargo, ¿qué pasa con aquellas circunstancias en las que necesita un constructor para realmente hacer cosas, aparte de simplemente enchufando argumentos en instan ¿variables ce?

// Java 
public class MyClass { 
    private String JDBC_URL = null; 
    private String JDBC_USER = null; 
    private String JDBC_PASSWORD = null; 

    public MyClass(String propertiesFilename) { 
     // Open a properties file, parse it, and use it to set instance variables. 
     // Log an error if the properties file is missing or can't be parsed. 
     // ... 
    } 
} 

¿Cómo funciona esto en Scala? Puedo tratar de definir una implementación para este constructor de este modo:

// Scala 
class MyClass(propertiesFilename: String) { 
    def this(propertiesFilename: String) { 
    // parse the file, etc 
    } 
} 

... pero me da un error de compilación, quejándose de que el constructor se define en dos ocasiones.

Pude evitar este conflicto teniendo un constructor por defecto no-arg, y luego declarando lo anterior como un constructor secundario sobrecargado. Sin embargo, ¿qué pasa con las situaciones en las que REALMENTE NECESITA un constructor "uno-y-uno-único", y usted necesita que haga algo?

Respuesta

19

Puede realizar estas acciones simplemente en el cuerpo de la clase.

Class Foo(filename: String) { 
    val index = { 
     val stream = openFile(filename) 
     readLines(stream) 
     ... 
     someValue 
    } 
    println(“initialized...“) 
} 
+0

Doh! Gracias, estoy llegando poco a poco ... –

3

Cualquier código se pone en el cuerpo de la clase se ejecuta en la construcción

class MyClass(propertiesFileName: String) { 
    println("Just created an instance of MyClass with properties in " + propertiesFileName) 
    val myFavoriteProperty = retrieveFavoriteFrom(propertiesFileName) 
} 

Puede ser un poco incómodo y sin duda no es una buena idea para intercalar su declaración de miembro y su inicialización código mucho, pero es un pequeño precio a pagar por la conveniencia de la sintaxis de inicialización variable

Cuestiones relacionadas