假设我有两个特性,我想将它们混入到一个类中。这些特性都实现了该类需要的抽象方法。
trait Writable {
def serialize(out: java.io.DataOutput)
}
trait T1 extends Writable
trait A extends T1 {
val aNum: Int
abstract override def serialize(out: java.io.DataOutput) = {
super.serialize(out)
println("A serialize")
out.writeInt(aNum)
}
def action = println("A action")
}
trait B extends T1 {
val bNum: Int
abstract override def serialize(out: java.io.DataOutput) = {
super.serialize(out)
println("B serialize")
out.writeInt(bNum)
}
def action = println("B action")
}
abstract class M[CT1 <: T1](val mNum: Int) extends Writable {
this: M[CT1] with T1 =>
def serialize(out: java.io.DataOutput) = {
println("M serialize")
out.writeInt(mNum)
}
def action
}
我可以使用 A 或 B 构建一个具体的 M 并将其序列化:
scala> val m1 = new M[A](10) with A { val aNum = 20 }
m1: M[A] with A = $anon$1@67c1e630
scala> val m2 = new M[B](20) with B { val bNum = 30 }
m2: M[B] with B = $anon$1@c36f58e
scala> val out = new java.io.DataOutputStream(new java.io.ByteArrayOutputStream())
out: java.io.DataOutputStream = java.io.DataOutputStream@87afebf
scala> m1.serialize(out)
M serialize
A serialize
scala> m2.serialize(out)
M serialize
B serialize
一切都按预期工作。但是,如何在尊重混入M的特质类型的同时反序列化对象?我可以在serialize方法中输出特质的名称,然后让M的deserialize方法根据名称进行调度,但如果除了M之外还有其他类可以将A和B混入其中怎么办?那么,每个类都必须复制M的调度反序列化行为。如果我有多个需要混入对象以使其具体化并且每个对象都有自己的自定义序列化/反序列化的特质,则问题会变得更加严重。有人解决过这样的问题吗?