我正在编写Clojure中的一些代码,这些代码非常依赖Apache Commons Math3库中的某些功能。我之前从未编写任何Java代码,并且正在尝试提出一个优雅的解决方案来创建我经常使用的一些clojure包装器。希望我能够传达我尝试做的事情,尽管不是真正的OOP或Java专家。我将用一个具体的简单例子描述挑战
一般来说,我有一个java类的集合,它们都从给定的接口继承了一些方法。举一个具体的例子,考虑distributions包。有3个接口,其中一个是RealDistribution。继承RealDistribution接口的类可以访问某些方法,例如" density"。
在clojure中,我可以做到
// First modify datasource
let businessObjectToInsert = BusinessObject() // or whatever your class is
self.businessArray.append(businessObject)
// Then insert row into `UITableView`
self.tableView.insertRows(at: [IndexPath(row: self.businessArray.count-1, section: 0)], with: UITableViewRowAnimation.automatic)
目标是编写多态函数"密度"它调度不同的发行版本身就是java类。
我可以写一个协议,称之为density-eval
(.density (new NormalDistribution 0 1) 2)
(.density (new ExponentialDistribution 1) 2)
并手动扩展每个分发,如
(defprotocol density-eval
(density [distribution x]))
但是我需要为每个发行版做这个......而且很多都是这样...并且每个发行版的代码都是相同的。
为了节省时间,我想做的是扩展一些更通用的东西...比如,NormalDistribution的父类型,但我不知道从哪里开始。我现在拥有的是
(extend-type NormalDistribution
density-eval
(density [d x] (.density d x)))
RealDistribution是NormalDistribution和ExponentialDistribution实现的接口。这工作......我可以调用(密度y x)实现RealDistribution接口的许多发行版y。例如(density(new NormalDistribution 0 1)0)工作正常。但是,这个问题是我为实现IntegerDistribution接口的类玩同一个游戏。我定义了一个新的协议
(extend-type RealDistribution
density-eval
(density [d x] (.density d x)))
然后对于实现IntegerDistribution接口的类,我可以做一些事情,比如(pmf(new PoissonDistribution 3)2)并且运行正常......但是我不能再在分布上调用(密度yx)y实现RealDistribution接口。我收到错误:
(defprotocol pmf-eval
(pmf [distribution x]))
(extend-type IntegerDistribution
pmf-eval
(pmf [d x] (.probability d x)))
当我在repl中以某种方式执行第二个协议代码时,它会干扰第一个协议代码。
最终我想为这些类的方法编写多态包装函数,但我不知道如何尽可能简单干净地完成这些操作。请指教......
答案 0 :(得分:1)
你写的内容应该没问题,但是如果有任何类实现这两个接口你会遇到麻烦。
至于为什么你说这不适合你:你确定吗? IntegerDistribution实际上没有density
参数,并且您的错误消息显示您实际上正在定义一个名为univariate-integer
的协议,而不是density-eval
,所以我想知道您在尝试简化时是否犯了错误并隔离Stack Overflow的问题。