在Traits中初始化值

时间:2015-01-21 20:28:44

标签: scala constructor initialization traits

我有一个庞大的课程,我希望打破许多特质。我班级的每个部分都有一组其他部分未使用的val。这些参数是从属性文件中读取的,有时会进行一些计算。我想让每个特性负责初始化自己的变量。我希望这些值对于特征是私有的。不幸的是,特征没有构造函数(这是我真正想要的)。

创建混合了一组特征的对象的模式是什么,其中特征具有需要初始化的值?

以下是一个例子:

class Foo( properties: Properties ) extends Bar with Baz

trait Bar {
 private val something
}

trait Baz {
 private val somethingElse
}

如何在不使用抽象和非私有的情况下初始化Bar.something和Baz.somethingElse,或者添加init()方法并使其成为变量?

谢谢 彼得

4 个答案:

答案 0 :(得分:2)

早期初始化怎么样?

trait A {
  val f: String
  val a = "I would have used " + f
}

trait B {
  val f: String
  val b = "I would have used " + f + " too!"
}

class C extends { val f = "the string" } with A with B

如果你把它扔进REPL:

scala> List(c.a, c.b).map(println _)
I would have used the string
I would have used the string too!

答案 1 :(得分:1)

好的,这是一种方式。还有更好的东西吗?

class Foo( val properties: Properties ) extends Bar with Baz

trait Bar {
  val properties: Properties
  private val something = properties.get("Something")
}

trait Baz {
  val properties: Properties
  private val somethingElse = properties.get("SomethingElse")
}

答案 2 :(得分:1)

你可以在那里进行计算。这是一个例子。

def readPropertyFile(s: String) = {
  println("Pretending to read " + s); 0
}

trait Bar {
  private val something = readPropertyFile("Bar.properties")
}

class Foo extends Bar {
  println("Hi, I am in class Foo")
}

scala> val foo = new Foo
Pretending to read Bar.properties
Hi, I am in class Foo
foo: Foo = Foo@27d8f985

只要您的资源是全球资源,您就可以轻松获取资源。如果没有,请将它们混合在较早的特征中。

答案 3 :(得分:0)

这是我最后使用的一种更清洁的方式

class Foo( val propertyFile: String ) extends Bar with Baz with Zot

trait Bar extends Properties {
  private val something = getProperty("Something")
}

trait Baz extends Properties {
  private val somethingElse = getProperty("SomethingElse")
}

trait Zot extends Properties {
  private val somethingWeird = getProperty("Something") + getProperty("SomethingElse")
}

trait Properties {
  val propertyFile: String
  private val properties = readProperties(propertyFile)
  protected def getProperty(name: String) = properties.get(name)
}