java - Clojure 中用于实现接口(interface)的 Java 类的多态性 - 包装器编写

标签 java oop inheritance clojure polymorphism

我正在用 Clojure 编写一些代码,这些代码在很大程度上依赖于 Apache Commons Math3 库中的某些功能。我以前从未编写过任何 Java 代码,并且正在尝试提出一个优雅的解决方案来创建一些我经常使用的 clojure 包装器。希望我能够传达我正在尝试做的事情,尽管我并不是真正的 OOP 或 Java 专家。我将用一个具体的简单示例来描述挑战

一般来说,我有一组 java 类,它们都从给定接口(interface)继承了一些方法。举一个具体的例子,考虑 distributions包裹。有 3 个接口(interface),其中一个是 RealDistribution。继承 RealDistribution 接口(interface)的类可以访问某些方法,例如“密度”。

在 Clojure 中我可以做到

(.density (new NormalDistribution 0 1) 2)
(.density (new ExponentialDistribution 1) 2)

目标是编写一个多态函数“密度”,它在不同的分布上调度,它们本身是 java 类。

我可以写一个协议(protocol),称之为密度评估

(defprotocol density-eval
  (density [distribution x]))

并手动扩展每个分布

(extend-type NormalDistribution
  density-eval
  (density [d x] (.density d x)))

但是我需要为每个发行版都这样做......而且有很多......并且每个发行版的代码都是相同的。

为了节省时间,我想做的是扩展一些更通用的东西...比如,NormalDistribution 的父类型,但我不知道从这里到哪里去。我目前拥有的是

(extend-type RealDistribution
  density-eval
  (density [d x] (.density d x)))

RealDistribution 是 NormalDistribution 和 ExponentialDistribution 实现的接口(interface)。这行得通......然后我可以为实现 RealDistribution 接口(interface)的许多分布 y 调用 (density y x)。例如 (density (new NormalDistribution 0 1) 0) 工作正常。但是,问题是我对实现 IntegerDistribution 接口(interface)的类玩同样的游戏。我定义了一个新协议(protocol)

(defprotocol pmf-eval
  (pmf [distribution x]))

(extend-type IntegerDistribution
  pmf-eval
  (pmf [d x] (.probability d x)))

然后对于实现 IntegerDistribution 接口(interface)的类,我可以做类似 (pmf (new PoissonDistribution 3) 2) 这样的事情,结果很好......但是我不能再调用 (density y x) 分布 y 实现RealDistribution 接口(interface)。我收到错误:

    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 中执行第二个协议(protocol)代码时,它以某种方式干扰了第一个。

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

最佳答案

你写的应该没问题,但如果有任何类同时实现这两个接口(interface),你会遇到麻烦。

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

关于java - Clojure 中用于实现接口(interface)的 Java 类的多态性 - 包装器编写,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42448718/

相关文章:

java - android.media.audiofx.Visualizer 每隔一段时间抛出异常

java - (需要解释)从计算机文件夹中检索图像

Javascript 时钟,落后几分钟

c++ - 具有多态性的多重保护继承

java - 简单的java,字符串长度

java - 在 GUI 中使用 GA

java - C2 编译器在启动时使 CPU 饱和

design-patterns - 建模对象的历史

c++ - 如何设计类方法只能被调用一次

java - 自定义注解参数化继承其他注解