我可以选择在defrecord的主体中直接实现协议,而不是使用extend-protocol/extend-type
(defprotocol Fly
(fly [this]))
(defrecord Bird [name]
Fly
(fly [this] (format "%s flies" name)))
=>(fly (Bird. "crow"))
"crow flies"
Run Code Online (Sandbox Code Playgroud)
如果我现在尝试覆盖Fly协议,我会收到错误
(extend-type Bird
Fly
(fly [this] (format "%s flies away (:name this)))
class user.Bird already directly implements interface user.Fly for protocol:#'user/Fly
Run Code Online (Sandbox Code Playgroud)
另一方面,如果相反,我最初使用extend-type
(defrecord Dragon [color])
(extend-type Dragon
Fly
(fly [this] (format "%s dragon flies" (:color this))))
=>(fly (Dragon. "Red"))
"Red dragon flies"
Run Code Online (Sandbox Code Playgroud)
然后我可以"覆盖"fly函数
(extend-type Dragon
Fly
(fly [this] (format "%s dragon flies away" (:color this))))
=>(fly (Dragon. "Blue"))
"Blue dragon …Run Code Online (Sandbox Code Playgroud) clojure ×1