我有一些扩展一个公共超类的case类,我想使用productElement
方法访问超类中的字段(我试图将基类声明为一个case类但是我得到一个可怕的警告关于继承案例类的危险,但是没有用。)
我可以想象这样的解决方案:
abstract class A(a: Int) extends Product {
def productArity = 1
def productElement(n: Int) = if (n == 0) a else throw new IndexOutOfBoundsException
}
case class B(b: Int) extends A(1) {
def productArity = super.productArity + 1
def productElement(n: Int) = if (n < super.productArity) super.productElement(n) else ....
}
但它变得如此丑陋以至于我甚至无法完成。
有人知道更好的解决方案吗?
答案 0 :(得分:4)
在Scala主干中,很多内容已经为您完成了:case类现在扩展了相应的ProductN特性。但是,只有case类直接(即非继承)成员才包含在产品中,因此如果需要包含超类型的成员,则它们必须在超类型中是抽象的,并在case类中给出具体实现。
这是一个REPL会话(Scala主干,2.10.0.r25951-b20111107020214),
scala> trait A { val a: Int }
defined trait A
scala> case class B(b: Int, a : Int = 1) extends A
defined class B
scala> val b = B(23)
b: B = B(23,1)
scala> b.productArity
res0: Int = 2
scala> b.productElement(0)
res1: Any = 23
scala> b.productElement(1)
res2: Any = 1
scala> b._1 // use Product method ... note result type
res6: Int = 23
scala> b._2 // use Product method ... note result type
res7: Int = 1
答案 1 :(得分:1)
我能得到的最接近的是在A
中没有实现任何东西scala> abstract class A(val a: Int) extends Product
defined class A
scala> case class B(override val a: Int, b: String) extends A(a)
defined class B
scala> val anA: A = B(42, "banana")
anA: A = B(42,banana)
scala> anA.a
res37: Int = 42
scala> anA.productArity
res38: Int = 2
scala> anA.productElement(1)
res39: Any = banana
scala> anA.productElement(0)
res40: Any = 42