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



据我所知,如果我使用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()
}

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

您可以这样做,但是您仍然必须保留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

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

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
}

听起来你只是想加入一个特征。而不是调用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.

相关内容

最新更新