Scala:我可以使用工厂方法重现匿名类创建吗?

时间:2011-10-02 04:10:35

标签: scala factory anonymous-class

据我了解,如果我使用new关键字创建一个类,并使用构造函数跟随类名,Scala会创建一个匿名类:

class MyClass {
  def doStuff() { 
    // ... 
  }
}

val mc = new MyClass {
  doStuff()
}

好处是构造函数中的所有代码都在新对象的范围内。

有没有办法可以重现这种语法,其中类是由工厂方法而不是new关键字创建的?即使以下代码有效:

val mf = new MyFactory

val mc = mf.MyClass { 
  doStuff() 
}

我找不到办法做到这一点,但Scala有很多东西,这可能很容易!

使用@Ricky建议的import,我可以得到:

val mf = MyFactory;
val mc = mf.MyClass

{
  import mc._
  doStuff()
}

(需要块之前的空行)但该代码块不是构造函数。

3 个答案:

答案 0 :(得分:2)

您可以执行此操作,但仍需保留new关键字,并将嵌套类创建为路径依赖类型:

class Bippy(x: Int) {
  class Bop {
    def getIt = x
  }
}

val bip = new Bippy(7)
val bop = new bip.Bop

bop.getIt // yields 7

val bop2 = new bip.Bop{ override def getIt = 42 }

bop2.getIt // yields 42

答案 1 :(得分:1)

我不认为这是可能的。但是,常见的模式是向工厂方法添加一个参数,该方法采用修改创建的对象的函数:

trait MyClass {
  var name = ""
  def doStuff():Unit
}

class Foo extends MyClass {
  def doStuff() { println("FOO: " + name) }
}

trait MyClassFactory {
  def make: MyClass
  def apply( body: MyClass => Unit ) = {
    val mc = make
    body(mc)
    mc
  }
}

object FooFactory extends MyClassFactory {
  def make = new Foo
}

然后,您可以使用接近示例的语法创建和修改实例:

val foo = FooFactory { f=>
  f.name = "Joe"
  f.doStuff
}

答案 2 :(得分:0)

听起来你只是想要混合一个特质。而不是调用理想情况下会执行的myFactoryMethod(classOf [Foo]](如果Scala允许的话):

new T {
  override def toString = "My implementation here."
}

你可以写

trait MyImplementation {
  override def toString = "My implementation here."
}

new Foo with MyImplementation

但是,如果您只是想要无限制地访问新对象的成员,请记住您可以从任何稳定的标识符导入:

val foo = new Bar
import foo._
println(baz) //where baz is a member of foo.