Reputation: 11860
Most of the time, a constructor for a class does nothing more than take its argument values and use them to set instance variables:
// Java
public class MyClass {
private int id;
public MyClass(int id) {
this.id = id;
}
}
So I understand the efficiency of Scala's default constructor syntax... simply declaring a list of variables in parentheses beside the class name:
// Scala
class MyClass(id: int) {
}
However, what about those circumstances where you need a constructor to actually DO STUFF, apart from simply plugging arguments into instance variables?
// 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.
// ...
}
}
How does this work in Scala? I can try to define an implementation for this constructor like so:
// Scala
class MyClass(propertiesFilename: String) {
def this(propertiesFilename: String) {
// parse the file, etc
}
}
... but I get a compilation error, complaining that the constructor is defined twice.
I could avoid this conflict by having a no-arg default constructor, and then declaring the above as an overloaded secondary constructor. However, what about situations in which you really DO need "one-and-only-one" constructor, and you need it to do stuff?
Upvotes: 17
Views: 7713
Reputation: 31053
You can perform these actions simply in the class body.
Class Foo(filename: String) {
val index = {
val stream = openFile(filename)
readLines(stream)
...
someValue
}
println(“initialized...“)
}
Upvotes: 27
Reputation: 29528
Any code you put in the body of the class is executed at construction
class MyClass(propertiesFileName: String) {
println("Just created an instance of MyClass with properties in " + propertiesFileName)
val myFavoriteProperty = retrieveFavoriteFrom(propertiesFileName)
}
It may be a little awkward and it is certainly not a good idea to interleave your member declaration and your initialization code a lot, but it is a small price to pay for the the convenience of the variable initialization syntax
Upvotes: 6