我希望可以互换使用几个类,它们都实现了一个方法“add”,所以我开始写一个 trait:
trait CanAdd{
def add(that: CanAdd): CanAdd
}
然后实现我的类并遇到一个问题:我不能与任何其他添加任何“CanAdd”,它们需要属于同一类。我用一些依赖“isInstanceOf”的丑陋代码解决了这个问题:
class A(val value: Int) extends CanAdd{
def add(that: CanAdd): CanAdd = {
if(!that.isInstanceOf[A]) sys.error("")
val thatA: A = that.asInstanceOf[A]
new A(value + thatA.value)
}
}
class B(val value: Boolean) extends CanAdd{
def add(that: CanAdd): CanAdd = {
if(!that.isInstanceOf[B]) sys.error("")
val thatB: B = that.asInstanceOf[B]
new B(value ^ thatB.value)
}
}
最后,我使用如下类:
class User(val stuff: Array[CanAdd]) {
def add(that: User): User = {
assume(stuff.length==that.stuff.length)
val out = new Array[CanAdd](stuff.length)
for( i <- 0 until stuff.length) out(i) = stuff(i).add(that.stuff(i))
new User(out)
}
}
val u1=new User(Array(new A(0)))
val u2=new User(Array(new B(false)))
val u3 = u1.add(u1)
val u4 = u1.add(u2) //should fail, ideally, should not even compile
我不喜欢它,因为首先用“isInstanceOf”编写样板代码是一种负担,其次因为它在运行时而不是编译时失败。
我的问题:你将如何做到这一点,考虑到一些计划来实现更多的方法,而不仅仅是“添加”,并且可能实现一些其他具有非常不同的内部表示的类?