如何将特征混合到实例中? [英] How to mix-in a trait to instance?
问题描述
给定一个特征MyTrait
:
trait MyTrait {
def doSomething = println("boo")
}
它可以与 extends
或 with
混合到一个类中:
it can be mixed into a class with extends
or with
:
class MyClass extends MyTrait
也可以在实例化新实例时混合使用:
It can also be mixed upon instantiating a new instance:
var o = new MyOtherClass with MyTrait
o.doSomething
但是...可以将特征(或其他任何有影响的特征)添加到现有实例中吗?
But...can the trait (or any other if that makes a difference) be added to an existing instance?
我正在使用 Java 中的 JPA 加载对象,我想使用特性向它们添加一些功能.有可能吗?
I'm loading objects using JPA in Java and I'd like to add some functionality to them using traits. Is it possible at all?
我希望能够混合如下特征:
I'd like to be able to mix in a trait as follows:
var o = DBHelper.loadMyEntityFromDB(primaryKey);
o = o with MyTrait //adding trait here, rather than during construction
o.doSomething
推荐答案
我对这个用法有个想法:
I have a idea for this usage:
//if I had a class like this
final class Test {
def f = println("foo")
}
trait MyTrait {
def doSomething = {
println("boo")
}
}
object MyTrait {
implicit def innerObj(o:MixTest) = o.obj
def ::(o:Test) = new MixTest(o)
final class MixTest private[MyTrait](val obj:Test) extends MyTrait
}
你可以使用这个特性如下:
you can use this trait as below:
import MyTrait._
val a = new Test
val b = a :: MyTrait
b.doSomething
b.f
对于您的示例代码:
val o = DBHelper.loadMyEntityFromDB(primaryKey) :: MyTrait
o.doSomething
希望能帮到你.
更新
object AnyTrait {
implicit def innerObj[T](o: MixTest[T]):T = o.obj
def ::[T](o: T) = new MixTest(o)
final class MixTest[T] private[AnyTrait](val obj: T) extends MyTrait
}
但是这个模式有一些限制,你不能使用一些已经定义的隐式辅助方法.
but this pattern has some restrict, you can't use some implicit helper method that defined already.
val a = new Test
a.f
val b = a :: AnyTrait
b.f1
b.f
val c = "say hello to %s" :: AnyTrait
println(c.intern) // you can invoke String's method
println(c.format("MyTrait")) //WRONG. you can't invoke StringLike's method, though there defined a implicit method in Predef can transform String to StringLike, but implicit restrict one level transform, you can't transform MixTest to String then to StringLike.
c.f1
val d = 1 :: AnyTrait
println(d.toLong)
d.toHexString // WRONG, the same as above
d.f1
这篇关于如何将特征混合到实例中?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!