如何在Scala中继承构造函数?

时间:2016-11-26 13:30:36

标签: scala inheritance constructor

如何改进以下代码?我不热衷于Subclass中的强制转换或对象Superclass和对象Subclass之间的重复

class Superclass {
  val bitSet = BitSet.empty  
  def += (bitSet:BitSet) = { this.bitSet | bitSet ; this }
  def += (ints:Array[Int]) = { ints.foreach { bitSet += _ } ; this }
  override def toString = bitSet.toString
}

object Superclass {
  def apply(bitSet:BitSet) = new Superclass += bitSet
  def apply(ints:Array[Int]) = new Superclass += ints
}

class Subclass extends Superclass {
  override def += (bitSet:BitSet) = (super.+= (bitSet)).asInstanceOf[Subclass]
  override def += (ints:Array[Int]) = (super.+= (ints)).asInstanceOf[Subclass]
}

object Subclass {
  def apply(bitSet:BitSet) = new Subclass += bitSet
  def apply(ints:Array[Int]) =  new Subclass += ints
}

object SubclassTest extends App {
  println(Subclass(Array(1,2,3)))
}

2 个答案:

答案 0 :(得分:2)

关于强制转换,您可以让Superclass方法返回父类'类型:

  def += (bitSet: BitSet): this.type = { this.bitSet | bitSet; this }

现在,您不需要覆盖它们:

  class Subclass extends Superclass
  val subclass: Subclass = new Subclass += BitSet.empty 

+=的返回值属于Subclass类型。

值得一提的是,您的+=方法无法执行任何操作:BitSet.|不会修改位集,只会返回一个副本,然后您会立即丢弃该副本。 另一个确实有效,但保持可变状态通常是不受欢迎的,除非你有一个非常非常好的理由(你很可能不会这样做)。

至于apply中的重复,你一般都无法做到这一点。在这种特殊情况下,我建议完全摆脱它,并使bitSet成为构造函数参数:

  class Superclass(val bitSet: BitSet = BitSet.empty) { 
   ...
  }
  class Subclass(bitSet: BitSet = BitSet.empty) 
    extends Superclass(bitSet)

现在,您可以执行

而不是apply
  new Subclass(bitSet)
  new Superclass(bitSet)

或       new Subclass()+ = ints       new Subperclass()+ = ints

答案 1 :(得分:1)

为了分解伴随对象的重复部分,您可以使用模板模式的变体。 (与可能的this.type一起使用)

trait Factory[T <: Superclass] {
  protected def create: T
  def apply(bitSet:BitSet): T = create += bitSet
  def apply(ints:Array[Int]): T = create += ints
}

object Superclass extends Factory[Superclass] {
  protected def create = new Superclass
}

object Subclass extends Factory[Subclass] {
  protected def create = new Subclass
}