次のクラス階層があります。
sealed abstract class A
case class B extends A
case class C extends A
foo
ここで、クラス、、、およびにメソッドをA
追加B
しますC
。しかし、私は決してクラスを変更したくありません。そこで、次のようにライブラリパターンをポン引きに適用します。
abstract class RichA(a: A) {
def foo
}
class RichB(b: B) extends RichA(b){
def foo = { println("B"); //do something with b}
}
class RichC(c: C) extends RichA(c) {
def foo = { println("C"); //do something with c}
}
/////////////
implicit def A2RichA(a: A) = {
a match {
case a: B => new RichB(a)
case a: C => new RichC(a)
}
}
implicit def B2RichB(b: B) = new RichB(b)
implicit def C2RichC(c: C) = new RichC(c)
/////////////
def test() = {
def printA(a: A) = {
a.foo
}
val obj = new C
printA(obj)
}
test() //This prints "C"
これはA2RichA
機能していますが、Aの各サブクラスのcaseステートメントが含まれているため、暗黙関数の実装は少し醜いように見えます。これをよりエレガントな方法で実行できますか?基本的な要件は、タイプのオブジェクトを呼び出す場合foo
、オブジェクトの動的タイプ内またはそれに応じてA
適切なメソッドを呼び出す必要があることです。foo
B
C