Soluzione con conversione implicita
Ken ha suggerito che un proxy potrebbe aiutarci in questo caso. Quello che stiamo cercando di fare qui è aggiungere un tratto all'istanza dopo che è stato creato. Questa "patch di scimmia" potrebbe essere utile se qualcun altro ha scritto la classe (e il metodo apply()
) e non è possibile accedere all'origine. In questo caso si può fare è aggiungere un proxy/involucro in cima alla esempio conversione implicita (nessuna conversione manuale necessario):
Utilizzando l'esempio Foo
potremmo fare questo in questo modo:
class Foo
object Foo { def apply() = new Foo }
trait Baz { def usefulMethod(s: String) = "I am really useful, "+ s }
// ---- Proxy/Wrapper ----
class FooWithBazProxy extends Foo with Baz
// --- Implicit conversion ---
implicit def foo2FooWithBazProxy(foo: Foo): FooWithBazProxy = new FooWithBazProxy
// --- Dummy testcode ---
val foo = Foo()
println(foo.usefulMethod("not!"))
Uscite:
I am really useful, not!
La ragione per cui non mi piace questo esempio è:
Baz
non utilizza Foo
in alcun modo.È difficile vedere il motivo per cui vorremmo collegare lo usefulMethod()
a Foo
.
Così ho fatto una nuova esempio in cui il tratto che "patch scimmia" in l'istanza in realtà utilizza l'istanza:
// --------- Predefined types -----------
trait Race {
def getName: String
}
class Avatar(val name: String) extends Race{
override def getName = name
}
object Avatar{
def apply() = new Avatar("Xerxes")
}
// ---------- Your new trait -----------
trait Elf extends Race {
def whoAmI = "I am "+ getName + ", the Elf. "
}
// ---- Proxy/Wrapper ----
class AvatarElfProxy(override val name: String) extends Avatar(name) with Elf
// ---- Implicit conversion ----
implicit def avatar2AvatarElfProxy(Avatar: Avatar): AvatarElfProxy = new AvatarElfProxy(Avatar.name)
// --- Dummy testcode ---
val xerxes= Avatar()
println(xerxes.whoAmI)
Stampe:
I am Xerxes, the Elf.
In questo esempio il tratto Elf
aggiunto usa il metodo getName
dell'istanza che estende.
Sarebbe grato se vedessi degli errori, non sono bravo a impliciti (ancora).
fonte
2010-08-03 10:33:51
possibile duplicato di [Come creare un'istanza di un tratto in un metodo generico in scala?] (Http://stackoverflow.com/questions/3274279/how-do-i-create-an-instance -di-un-trait-in-un-generico-metodo-in-scala) –