我有一个工厂对象,它创建了一些元素的实例(这是一个内部类型)。我还有一个适用于工厂创建的元素的操作。这是代码:
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
抽象的情况下实现相同的结果?
答案 0 :(得分:2)
您可以使用Factory#Element
告诉apply
期望在Element
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