Реализация единого конструктора Scala, который делает больше, чем просто устанавливает переменные - PullRequest
15 голосов
/ 16 июня 2011

Большую часть времени конструктор для класса делает не что иное, как принимает значения аргументов и использует их для установки переменных экземпляра:

// 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
  }
}

... но я получаю ошибку компиляции, жалуясь, что конструктор определяется дважды.

Я мог бы избежать этого конфликта, имея конструктор по умолчанию без аргументов, а затем объявив вышеприведенный перегруженный вторичный конструктор. Однако как насчет ситуаций, в которых вам действительно нужен конструктор «один-единственный-один», и он вам нужен для работы?

Ответы [ 2 ]

23 голосов
/ 16 июня 2011

Вы можете выполнять эти действия просто в теле класса.

Class Foo(filename: String) {
    val index =  {
         val stream = openFile(filename)
         readLines(stream)
         ...
         someValue
     }
     println(“initialized...“) 
}
5 голосов
/ 16 июня 2011

Любой код, введенный вами в тело класса, выполняется при построении

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

Это может быть немного неловко, и, конечно, не очень хорошая идея чередовать объявление вашего члена и ваш код инициализации, но это небольшая цена за удобство синтаксиса инициализации переменной

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...