案例类中的产品继承

时间:2011-10-31 13:48:28

标签: scala inheritance case-class

我有一些扩展一个公共超类的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 ....
}

但它变得如此丑陋以至于我甚至无法完成。

有人知道更好的解决方案吗?

2 个答案:

答案 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