实现单个 Scala 构造函数,该构造函数的作用不仅仅是设置变量

2022-09-03 05:02:37

大多数情况下,类的构造函数只执行其参数值并使用它们来设置实例变量:

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

这可能有点尴尬,并且将成员声明和初始化代码交错很多肯定不是一个好主意,但是为了变量初始化语法的便利性而付出的代价很小


推荐