如何确定是否在Smalltalk中的对象的祖先类中定义了方法

Wes*_*eld 3 inheritance smalltalk squeak parent ancestor

好的,所以我正在Smalltalk的一个学校作业,基本上它的要点是我写了3个"手动"设置和覆盖方法的类.MyObject类包含在另一个类ManualTracer中,该类继承自ObjectTracer.

MyObject包含一个类变量manualSet,它是一组符号,指定手动为其分配哪些方法,即重写继承.这个设置是使用类方法manualSet声明的:它接受一组符号.我的问题是我需要这个manualSet来根据以下标准过滤掉它收到的集合:

  1. 不在继承链中(作为非手动方法,直到并包括MyObject).
  2. 实际上不是手动方法.(通过方法检查是手动的)
  3. 一个实际的手动方法,但是父类(包括祖先)类已经具有该方法(通过专门继承它,或者通过覆盖它).

通过在源代码中包含注释"@Manual"来检查手动方法.到目前为止,我的代码如下所示:

manualSet: aSet
| validatedSet |
( aSet == nil ) ifTrue: [ manualSet:= nil ] 
ifFalse: [ 
    (aSet isMemberOf: Set) ifFalse:[^nil]. 
    validatedSet:= aSet select:[ :each| (each isMemberOf:Symbol)
                                    and:(self respondsTo:each)
                                    and:(self isManual:each in: self) 
                                    and:((self isManual:each in:super)not)].
    manualSet:= validatedSet.
]
Run Code Online (Sandbox Code Playgroud)

所以"超级"显然不够好,我需要经历所有的祖先,而不仅仅是父母.我还需要查看所有祖先的评论,并确定它们是否包含"@Manual".任何帮助都将非常感谢,谢谢!

Uko*_*Uko 5

您可以使用allSuperclasses方法获取所有祖先.例如:

Integer allSuperclasses
Run Code Online (Sandbox Code Playgroud)

将返回

an OrderedCollection(Number Magnitude Object ProtoObject)
Run Code Online (Sandbox Code Playgroud)

然后你可以用它allSatisfy: aBlock来看看他们是否没有这种方法.

我认为你的代码看起来像这样:

manualSet: aSet
| validatedSet |
( aSet == nil ) ifTrue: [ manualSet:= nil ] 
ifFalse: [ 
    (aSet isMemberOf: Set) ifFalse:[^nil]. 
    validatedSet:= aSet select:[ :each|
        (each isMemberOf:Symbol)
        and:(self respondsTo:each)
        and:(self isManual:each in: self) 
        and:(self allSuperclasses allSatisfy: [:class |
            (self isManual:each in:class) not])].
    manualSet:= validatedSet.
]
Run Code Online (Sandbox Code Playgroud)