类方法中的"超级"关键字

Woj*_*tak 6 inheritance smalltalk class-method

我正在学习Smalltalk的基础知识.有一个super关键字用于从子类方法中的超类调用方法:

Object subclass: # A
   test
      ^1

A subclass: # B
   test
      ^2
   callSuper
      ^super test
Run Code Online (Sandbox Code Playgroud)

所以B new callSuper评估为1.

好.这很清楚.

所以现在,我正在为B类定义一堆类方法:

createNew1
    ^super new
createNew2
    ^self new
create
    ^self
createSuper
    ^super
Run Code Online (Sandbox Code Playgroud)

他们分别计算结果为a B,a B,B和一个错误(这说明我super是不是继承而是一种消息分派器的投).

为什么我会在关键字的情况下获得B课程实例supera BB对象有什么区别?我开始认为B对象是一个特殊的,单一的实例(就像static属性在其他语言中实现的)B,但仍然 - 我已经检查过它的类是一个B和子类是一个A.

super类方法中关键字的语义是什么?它与对象方法中的语义有何不同?通过调用self类方法可以获得的对象究竟是什么?

Woj*_*tak 2

尽管所有其他答案在技术上都是正确的,但我将自己回答这个问题。那是因为我了解元类,而且super我的头脑中似乎有正确的语义,但我仍然得到了意想不到的结果。

事实证明,我误解了 Smalltalk 中继承的基础以及方法的调用方式。

我想对于这样的代码......

Object subclass: #A
    test
        ^'A'
    getTest
        ^self test

A subclass: # B
    test
        ^'B'
    runTest
        ^super getTest
Run Code Online (Sandbox Code Playgroud)

...表达式的B new runTest计算结果为'A'- 这意味着,超类中的方法在向上转换的对象中计算。

但事实并非如此。

它被评估为'B',因为没有向上转换,并且当我们在超类方法内调用任何方法时 - 搜索从对象的真实类开始,而不是从评估方法来源的类开始。

因此,调用^self new^super new,虽然没有在任何类中定义 a new,但具有相同的效果 - 因为它们最终都会在 的上下文中调用Behaviour 的 实现。newself