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

时间:2013-05-08 20:43:14

标签: inheritance parent smalltalk squeak ancestor

好的,所以我正在Smalltalk上完成一项学校作业,基本上我要写的是3个“手动”设置和覆盖方法的类。 MyObject类包含在另一个类ManualTracer中,该类继承自ObjectTracer。

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

  1. 不在继承链中(作为非手动方法,直到并包括MyObject)。
  2. 实际上不是手动方法。(通过方法检查是手动的)
  3. 一个实际的手动方法,但是父类(包括祖先)类已经有了这个方法(通过专门继承它,或者通过覆盖它)。
  4. 通过在源代码中包含注释“@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.
    ]
    

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

1 个答案:

答案 0 :(得分:5)

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

Integer allSuperclasses

将返回

an OrderedCollection(Number Magnitude Object ProtoObject)

然后您可以使用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.
]