Реализация одного конструктора Scala, который делает больше, чем заданные переменные
В большинстве случаев конструктор для класса не более чем принимает значения аргумента и использует их для установки переменных экземпляра:
// Java
public class MyClass {
private int id;
public MyClass(int id) {
this.id = id;
}
}
Итак, я понимаю эффективность синтаксиса конструктора Scala по умолчанию... просто объявляя список переменных в круглых скобках рядом с именем класса:
// Scala
class MyClass(id: int) {
}
Однако, как насчет тех обстоятельств, когда вам нужен конструктор, чтобы на самом деле делать STUFF, кроме простого подключения аргументов к переменным экземпляра?
// 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.
// ...
}
}
Как это работает в Scala? Я могу попытаться определить реализацию для этого конструктора следующим образом:
// Scala
class MyClass(propertiesFilename: String) {
def this(propertiesFilename: String) {
// parse the file, etc
}
}
... но я получаю ошибку компиляции, жалуясь, что конструктор определяется дважды.
Я мог бы избежать этого конфликта, создав конструктор по умолчанию no-arg, а затем объявив выше как перегруженный вторичный конструктор. Однако, как насчет ситуаций, в которых вам действительно нужен конструктор "один-единственный-один", и вам нужно это делать?
Ответы
Ответ 1
Вы можете выполнять эти действия просто в теле класса.
Class Foo(filename: String) {
val index = {
val stream = openFile(filename)
readLines(stream)
...
someValue
}
println("initialized...")
}
Ответ 2
Любой код, который вы помещаете в тело класса, выполняется при построении
class MyClass(propertiesFileName: String) {
println("Just created an instance of MyClass with properties in " + propertiesFileName)
val myFavoriteProperty = retrieveFavoriteFrom(propertiesFileName)
}
Это может быть немного неудобно, и, конечно же, не очень хорошо чередоваться с объявлением участника и кодом инициализации, но это небольшая цена, чтобы заплатить за удобство синтаксиса инициализации переменной