问题
- 各种Java API依赖于扩展抽象基类而不是接口
- "proxy" 有限制(无法访问受保护的字段或super)
- "proxy"由于额外的功能层(如函数/参数装箱等)而具有性能开销
- "gen-class" 复杂且与编译/字节码生成相关联
总结:Clojure目前没有一种很好的/便捷的方式来动态地扩展Java抽象基类。
建议创建一个 "reify" 变种,允许扩展单个抽象基类(可选地还包括接口/协议)。代码生成会在仿佛抽象基类已经在Java中直接扩展的情况下发生(即,具有完全访问受保护的成员以及完全类型提示的字段)。
由于这是一个仅适用于JVM的结构,它不应影响Clojure的可移植扩展方法(如deftype等)。我们建议将其放入一个单独的命名空间,这可能成为其他JVM特定互操作功能的家,例如 "clojure.java.interop"。
建议的解决方案:附加的补丁提出了此功能的实现,提供一个包含 defclass
和 extend-class
宏的新 clojure.interop
命名空间。
`
``(defclass name [fields*] options super-class super-args specs)
类似于 clojure.core/deftype,但是可以扩展具体的类,重写
并调用在超类或其基类中定义的公共和受保护方法,以及访问/设置这些的公共和受保护字段
。
super-args 是传递给超类构造函数的(可能是空的)向量参数
。
。
可以通过将参数 this
类型提示为超类来调用覆盖的方法,例如:(. ^SuperClass this method args*)"
``
`
``(extend-class options super-class super-args specs)
类似于 clojure.core/reify,但是可以扩展具体的类,重写
并调用在超类或其基类中定义的公共和受保护方法,以及访问/设置这些的公共和受保护字段
。
super-args 是传递给超类构造函数的(可能是空的)向量参数
。
。
可以通过将参数 this
类型提示为超类来调用覆盖的方法,例如:(. ^SuperClass this method args*)"
可以通过将参数 this
类型提示为超类来调用覆盖的方法,例如:(. ^SuperClass this method args*)"
``