Implementing a single Scala constructor that does more than set variables

Viewed 7006

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?

2 Answers
Related