решения с неявным преобразованием
Кен предположил, что прокси-сервер может помочь нам в этом случае. То, что мы пытаемся сделать здесь, - добавить черту к экземпляру после его создания. Это «исправление обезьян» может быть полезно, если кто-то написал класс (и метод apply()
), и вы не можете получить доступ к источнику. В этом случае вы можете сделать, это добавить прокси/обертку поверх экземпляра с помощью неявного преобразования (без ручного преобразования требуется):
Используя Foo
пример мы могли бы сделать это так:
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!"))
Выходы:
I am really useful, not!
причина мне не нравится этот пример является:
Baz
не использует Foo
в любом случае.Трудно понять, почему мы хотели бы присоединить usefulMethod()
к Foo
.
Так что я сделал новый пример, где черта мы «обезьяна патч» в экземпляр фактически использует экземпляр:
// --------- 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)
Печать:
I am Xerxes, the Elf.
В этом примере добавленный признак Elf
использует метод getName
экземпляра, который он расширяет.
Был бы благодарен, если вы увидели какие-либо ошибки, я не очень хорошо разбираюсь (пока).
Возможный дубликат [Как создать экземпляр признака в общем методе в scala?] (Http://stackoverflow.com/questions/3274279/how-do-i-create-an-instance -of-a-trait-in-a-generic-method-in-scala) –