"super" keyword in class method

class-method, inheritance, smalltalk

Solution

I'm going to answer this by myself despite that all the other answers are technically correct. That's because I was knowing about metaclasses and it seems that I have a proper semantics of `super` in my head, yet I was still getting unexpected results.

Turns out that I've misunderstood the basis of inheritance in Smalltalk and how methods are called.

I was thinking that for such code ...

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

A subclass: # B
    test
        ^'B'
    runTest
        ^super getTest

... the expression `B new runTest` is evaluated to `'A'` - that means, the method from the superclass is evaluated in upcasted object.

But it isn't.

It's evaluated to `'B'`, because there's no upcasting and when we're calling any method inside a superclass method - the search starts in the real class of the object, not class from which evaluated method comes.

As a result, calling `^self new` and `^super new`, while not defining a `new` in any of the classess, have the same effect - since both of them ends up with calling Behaviour's `new` implementation in the context of `self`.

Problem

I'm learning a basics of Smalltalk. There's a `super` keyword which is used to call a method from superclass inside a subclass method: ``` Object subclass: # A test ^1 A subclass: # B test ^2 callSuper ^super test ``` So `B new callSuper` evaluates to `1`. OK. That's clear. So now, I'm defining a bunch of class methods for `B` class: ``` createNew1 ^super new createNew2 ^self new create ^self createSuper ^super ``` And they evaluates respectively to `a B`, `a B`, `B` and an error (which shows me that `super` is not a cast to subclass but kind of a message dispatcher). Why am I getting instances of `B` class despite `super` keyword? And what's a difference between `a B` and `B` objects? I've started to think that the `B` object is a special, singletone instance (just like `static` attributes are implemented in other languages) of class `B`, but still - I've checked and it's class is a `B` and subclass is an `A`. What is the semantics of `super` keyword in class methods? How it differs from semantics inside objects methods? What really is the object which can be obtained by calling `self` inside class method?

Original source