我在编写Clojure中的一些代码中间,这在很大程度上依赖于Apache Commons Math3库中的某些功能。我以前从未编写过任何Java代码,并且正在尝试提出一种优雅的解决方案来创建一些我经常使用的Clojure包装器。希望尽管不是真正成为OOP或Java专家,但我将能够传达我试图做的事情。我将用一个具体的简单示例来描述挑战
一般而言,我有一个Java类的集合,这些类都从给定的接口继承了一些方法。要举一个具体示例,请考虑分布包。有3个接口,其中一个是重新分布。继承重新分布接口的类可以访问某些方法,例如"密度"。
在Clojure我可以做
(.density (new NormalDistribution 0 1) 2)
(.density (new ExponentialDistribution 1) 2)
目的是编写一个多态函数"密度",该功能在不同的分布上派遣,本身Java类。
我可以编写协议,称其为密度 - eval
(defprotocol density-eval
(density [distribution x]))
并手动扩展每个分布
(extend-type NormalDistribution
density-eval
(density [d x] (.density d x)))
但是,我需要为每个分布做到这一点...并且其中很多...代码对于每个分布都是相同的。
为了节省时间,我想做的就是扩展一些更通用的东西...例如,正常分布的父母类型,但我不知道从这里去哪里。我目前拥有的是
(extend-type RealDistribution
density-eval
(density [d x] (.density d x)))
重新分布是正常分布和实现的接口。这起作用...然后,我可以为实现重新分布接口的许多分布y致电(密度y x)。例如(密度(新的常规分布0 1)0)0)工作正常。但是,问题在于我为实现IntegerDistribution接口的类玩了同一游戏。我定义了一个新协议
(defprotocol pmf-eval
(pmf [distribution x]))
(extend-type IntegerDistribution
pmf-eval
(pmf [d x] (.probability d x)))
,然后对于实现IntegerDistribution接口的类,我可以做(PMF(PMF(新Poissondistribution 3)2)2),并且可以很好地工作...但是,我再也无法在分布y上拨打(密度y x)重新分布接口。我有错误:
1. Unhandled java.lang.IllegalArgumentException
No implementation of method: :density of protocol:
#'distributions.core/density-eval found for class:
org.apache.commons.math3.distribution.NormalDistribution
当我以某种方式在repl中执行第二个协议代码时,它会干扰第一个。
最终,我想为这些类的方法编写多态性包装器功能,但我不知道如何尽可能简单明了。请告知...
您编写的内容应该没问题,尽管如果有任何类两个接口的类,您会遇到麻烦。
为什么您说这不适合您:您确定吗?IntegerDistribution实际上没有density
参数,您的错误消息显示您实际上定义了一个名为univariate-integer
而不是density-eval
的协议,因此我想知道您在尝试简化并隔离堆栈溢出问题时是否遇到了错误。