尝试在具有两个“相互递归”方法但不成功的特征中的覆盖方法之外调用“ super”

问题描述

最近我正在学习球拍的特质系统。

我通过两种相互递归的方法super进行了一些实验:

我首先尝试了mixin,它可以按预期工作:

#lang racket

(define fish%
  (class object% (super-new)
    (define/public (get-color)
      (println "fish% get-color"))
    (define/public (get-price)
      (println "fish% get-price"))
    ))

(define (spots-mixin %)
  (class % (super-new)
    (define/override (get-color)
      (println "spots-mixin get-color")
      (super get-price))
    (define/override (get-price)
      (println "spots-mixin get-price")
      (super get-color)) ))

(define spots%
  (spots-mixin fish%))

(send (new spots%) get-color)
(send (new spots%) get-price)

; Output:
; "spots-mixin get-color"
; "fish% get-price"
; "spots-mixin get-price"
; "fish% get-color"

然后我尝试了该特征,但失败了:

#lang racket
(require racket/trait)

(define fish%
  (class object% (super-new)
    (define/public (get-color)
      (println "fish% get-color"))
    (define/public (get-price)
      (println "fish% get-price"))
    ))

(define spots-trait
  (trait
   (define/override (get-color)
     (println "spots-trait get-color")
     (super get-price))
   (define/override (get-price)
     (println "spots-trait get-price")
     (super get-color))
   ))

(define spots%
  ((trait->mixin spots-trait) fish%))

(send (new spots%) get-color)
(send (new spots%) get-price)

REPL告诉我:

; class*: superclass does not provide an expected method for override
;   override name: member68863
;   class name: ...cts/racket/trait.rkt:367:17

我只在超类fish%中定义2个方法,而在特征spots-trait中定义2个方法来覆盖它们。

为什么要superclass does not provide an expected method for override

是否可以解决错误

顺便说一句,如果我在(inherit/super get-color get-price)中声明了另外的spots-trait,则REPL将投诉:

get-color: duplicate deFinition of external name in trait
;   in: get-color

非常感谢!


更新:

最近我重新阅读了论文《具有类,混合素和特征的方案》,其中提到

如果在除覆盖实现之外的方法中允许超级调用,则需要特别注意,并且相互调用方法的循环可能需要间接操作,以防止超级调用访问特征中的实现,而不是基类。幸运的是,特征应用程序操作员可以自动生成此间接调用

这似乎与问题有关,但我不太明白这是什么意思。 (例如什么是“间接”)。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)