实现接口的Java类的Clojure中的多态性 - 包装器编写

时间:2017-02-24 21:37:09

标签: java oop inheritance clojure polymorphism

我正在编写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中以某种方式执行第二个协议代码时,它会干扰第一个协议代码。

最终我想为这些类的方法编写多态包装函数,但我不知道如何尽可能简单干净地完成这些操作。请指教......

1 个答案:

答案 0 :(得分:1)

你写的内容应该没问题,但是如果有任何类实现这两个接口你会遇到麻烦。

至于为什么你说这不适合你:你确定吗? IntegerDistribution实际上没有density参数,并且您的错误消息显示您实际上正在定义一个名为univariate-integer的协议,而不是density-eval,所以我想知道您在尝试简化时是否犯了错误并隔离Stack Overflow的问题。