如何将特征混合到实例中? [英] How to mix-in a trait to instance?

查看:23
本文介绍了如何将特征混合到实例中?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给定一个特征MyTrait:

trait MyTrait {
  def doSomething = println("boo")
}

它可以与 extendswith 混合到一个类中:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆