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