问题
- 各类Java API依赖于抽象基类的扩展而不是接口
- “proxy”存在限制(无法访问受保护的字段或超类)
- “proxy”因为额外的函数层和参数装箱等原因而带来性能开销
- “gen-class”复杂,并且与编译/字节码生成相关联
总之:Clojure目前没有好的/方便的方法来动态扩展Java抽象基类。
建议创建“reify”的一种变体,允许扩展单个抽象基类(可选地也扩展接口/协议)。代码生成将像直接在Java中扩展抽象基类一样发生(即,完全访问受保护的成员,以及完全类型提示的字段)。
由于这是一个仅适用于JVM的结构,它不应影响Clojure中的可移植扩展方法(deftype等)。我们建议将其放在一个单独的命名空间中,这可以作为其他JVM特定互操作功能的家园,例如“clojure.java.interop”。
建议的解决方案:所附补丁为该功能提出了一种实现方法,提供了一个新的clojure.interop
命名空间,其中包含defclass
和extend-class
宏。
`
"(defclass name [fields*] options 超类 super-args 规范)"
类似于clojure.core/deftype但可以扩展具体类、重写并调用在超类或其基类中定义的公共和保护方法;访问/设置那些的公共和保护字段。
super-args是一个(可能为空的)构造函数的参数向量
通过类型提示参数作为超类,可以在重写超方法的同时调用它:(. ^SuperClass this method args*)"
`
`
"(extend-class options 超类 super-args 规范)`
类似于clojure.core/reify但可以扩展具体类:重写并调用作为超类参数:(. ^SuperClass this method args*)"`
super-args是一个(可能为空的)构造函数的参数向量
通过类型提示参数作为超类,可以在重写超方法的同时调用它:(. ^SuperClass this method args*)"
补丁: 0001-CLJ-1225-add-defclass-extend-class-v2.patch
请求: jira