たとえば、次のクラス階層があります。
abstract class A {
def a() {}
def aa()
}
class B extends A {
def aa() {}
def b()
}
class C extends A {
def aa() {}
def c()
}
そして、これらのクラス インスタンスの任意の組み合わせのコレクションを格納できるクラスを作成したいと考えています。一般的なメソッドを呼び出すことができます。また、型のパラメーター化により、作成時にこれらのクラスでパラメーター化されている場合は、クラス固有のメソッドを呼び出す機能を提供する必要があります。
object Group {
def apply(as: Buffer[A]) = new Group[A](as)
def apply[T <: A](as: Buffer[T]) = new Group[T](as)
}
class Group[T <: A](as: Buffer[T]) {
def a() { as.map(_.a()) }
def aa() { as.map(_.aa()) }
}
したがって、次のGroup
ようなデフォルトの最も一般的な型パラメーターを使用して作成できます。
val groupA = Group(Buffer[A]())
groupA.a() //ok
groupA.aa() //ok
groupA.b() //error
groupA.c() //error
の子孫の 1 つを使用して明示的にパラメーター化すると作成できますA
。
val groupB = Group[B](Buffer[B]())
groupB.a() //ok
groupB.aa() //ok
groupB.b() //ok
groupB.c() //error
[B]
可能であれば、渡されたバッファタイプから抽出できるため、グループを作成するときに不要なタイプ指定を削除したいと思います。
val groupB = Group(Buffer[B]())
この機能を実現する正しい方法は何ですか? 出来ますか?これを達成するためのより良いアーキテクチャ上の決定があるのでしょうか?
更新:ここのコードは疑似コードです。必要なものを記述する方法がわかりません。
更新 2:b()
またはのような型固有のメソッドの呼び出しc()
は、マッピングを通じて実現する必要があると思います。
groupC.as.map(_.c())
これは、型のパラメーター化が正しい場合にのみ可能です。それは私の考えに近づきますが、実現可能な正確な方法は謎のままです(asInstanceOf
物事の多くの使用法は別として)。