如何改进以下代码?我不热衷于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)))
}
答案 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
}