0

我有一个工厂对象,它创建某个元素的实例(即内部类型)。我还有一个对工厂创建的元素起作用的操作。这是代码:

class Factory {
  class Element private [Factory] (val int:Int)
  def create(from:Int) = new Element(from)
}

class OperationOnFactoryElement(val factory:Factory) {
  def apply(element:factory.Element) = factory.create(element.int + 1)
}

val factory = new Factory

val op = new OperationOnFactoryElement(factory)

val someElement = factory.create(1)

op(someElement) // this causes an error!!

//<console>:13: error: type mismatch;
// found   : factory.Element
// required: op.factory.Element
//              op(someElement)
//                 ^

很明显,编译器希望我使用嵌入的工厂OperationOnFactoryElement来接受操作。但是,如果我需要在该元素上定义更多操作,这将成为一个问题,因为我不能,例如组合这两个操作。我想出了这个解决方案:

class Factory {
  class Element private [Factory] (val int:Int)
  def create(from:Int) = new Element(from)
}

abstract class OperationOnFactoryElement {
  val factory:Factory
  def apply(element:factory.Element) = factory.create(element.int + 1)
}

val myfactory = new Factory

val op = new OperationOnFactoryElement {
val factory:myfactory.type = myfactory
}
val someElement = myfactory.create(1)

op(someElement) // this works

但是,我不得不将我的操作变成一个抽象类。我的问题是:

有没有办法在不使类OperationOnFactoryElement抽象的情况下达到相同的结果?

4

1 回答 1

2

您可以使用Factory#Elementto tellapply期望Element在 a 中定义Factory

 class OperationOnFactoryElement(val factory:Factory) {
   def apply(element:Factory#Element) = factory.create(element.int + 1)
 }

通过此更改,您的第一个代码示例应该可以按原样工作。

scala> class Factory {
     |   class Element private [Factory] (val int:Int)
     |   def create(from:Int) = new Element(from)
     | }
defined class Factory

scala> class OperationOnFactoryElement(val factory:Factory) {
     |    def apply(element:Factory#Element) = factory.create(element.int + 1)
     |  }
defined class OperationOnFactoryElement

scala> val factory = new Factory
factory: Factory = Factory@650b5efb

scala> val op = new OperationOnFactoryElement(factory)
op: OperationOnFactoryElement = OperationOnFactoryElement@33abb81e

scala> val someElement = factory.create(1)
someElement: factory.Element = Factory$Element@bebf1eb

scala> op(someElement)
res0: op.factory.Element = Factory$Element@6176959c

scala> someElement.int
res1: Int = 1

scala> res0.int
res2: Int = 2
于 2013-09-30T10:19:30.150 回答