我经常遇到想要为我无法控制的类添加其他方法的问题.例如,我可能想要一个prettyPrint可以在没有统一api的不同对象类型上运行的函数(例如特殊__str__方法).
在Nice语言和R实现这一使用多方法,避免了访问者模式很好.例如,R有plot()功能.各个程序员可以创建新类来定义数据类型(例如,网络图或股票行情数据).然后,辅助用户/程序员可以编写绘图功能来填写功能,即使他们无法访问图表或股票代码或其他绘图功能的代码.
鉴于我想在以后添加许多功能,使用class.method()似乎不可行.class_plot()每种类型的许多功能似乎也是一个坏主意.定义一个plot()检查类型的大函数是不可扩展的.
什么是多方法的替代方案?特别是,我对可能在Jython和Scala中工作的设计感兴趣.
在Scala中向类添加方法的最简单方法:
implicit def defSum(l: List[Double]): Double = new AnyRef { def sum = l.foldLeft(0.0)(_ + _) }
Run Code Online (Sandbox Code Playgroud)
或者,在Scala 2.8上,使用处理数字的方法的特殊情况,
implicit def defSum[T](l: List[T])(implicit n: Numeric[T]) = new AnyRef {
import n.mkNumericOps
def sum = l.foldLeft(n.zero)(_ + _)
}
Run Code Online (Sandbox Code Playgroud)
Scala 2.8上不需要这个,因为它sum已经定义了.
您还可以在实例化时添加特征:
// Immutable class
case class Point(x: Int, y: Int)
// Somewhere else in the code
trait MyPlot {
self: Point =>
import self._
def plot = println("At "+x+", "+y)
}
// Usage
val p = new Point(1,2) with MyPlot
p.plot
Run Code Online (Sandbox Code Playgroud)
你不能做的是动态地(即,在运行时而不是编译时)向对象添加方法.在第一种情况下,您说"将此方法添加到此类".在第二种情况下,您说"使用此特征创建此对象".这些都没问题,但"将此方法添加到此对象"则不行.