super keyword in class method

I am learning the basics of Smalltalk. There is the super keyword, which is used to call a method from a 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 It is clear.

So now I am defining a bunch of class methods for class B :

 createNew1 ^super new createNew2 ^self new create ^self createSuper ^super 

And they evaluate respectively a B , a B , B and the error (which shows me that super not a subclass, but a message manager).

Why am I getting instances of class B despite the super keyword? And what is the difference between objects a B and B ? I began to think that object B is a special, single instance (just like static attributes are implemented in other languages) of class B , but still - I checked that this class is B and the subclass is A

What is super keyword semantics in class methods? . How does it differ from semantics within object methods? What really is an object that can be obtained by calling the self method inside the class?

+6
source share
5 answers

I myself will answer this, despite the fact that all other answers are technically correct. This is because I knew about metaclasses, and it seems that I have the correct super semantics in my head, but I was still getting unexpected results.

It turns out that I misunderstood the basics of inheritance in Smalltalk and how the method is called.

I thought 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 as 'A' - this means that the method from the superclass is evaluated in the enlarged object.

But this is not so.

It is evaluated as 'B' because there is no promotion, and when we call any method inside the superclass method, the search starts in the real class of the object, and not in the class from which the evaluation method is derived.

As a result, calling ^self new and ^super new , although not defining a new in any of the classes, has the same effect, since both of them end with a call to the implementation of new Behavior in the context of self .

+1
source

self and super always refer to the same object, the current receiver. The only difference is that self starts a search for the next dispatch method in the receiver class and super to the superclass where the method is defined.

See Chapter 5 of Pharo for an example .

+4
source

Your answer to the first example is incorrect. B new callSuper returns 1. Lucas gave you the exact definition of super semantics. This is basically an alias for self that changes the method of searching for a message sent to it. self message will start searching for methods in the receiver class, super message will start searching in the superclass of the class that defines the method containing the super message expression (therefore, the receiver class is not relevant to this case).

In your second example, super new and self new will eventually call the same method (defined somewhere in the hierarchy of behavior), because this is the closest definition of the new method in both cases. If, however, you renamed the createNew methods to new, then new ^self new will be an infinite loop, while new ^super new calls the Behavior method.

+4
source

self and super mean the same thing in a class or object, because the class is an object ...

# createNew1 and # createNew2 are equivalent. As Lucas explained, super simply means "start looking for a method in my superclass, not my class." Since you did not specify #new in A or B, you will search for superclasses, eventually find Behavior → # new, whether you start in A or B. #new starts by calling #basicNew, which creates and returns a new instance of B (i.e. . "a B").

In #create and #createSuper, since you are not looking for anything, self and super are again equivalent and mean "return the current object" (what did you mean for the latter?). Now this part is confusing. Since everything in Smalltalk is an object, this includes classes. So, in this context, the “current object” is B, which is the only instance of the metaclass “class B”. If you are really interested in understanding, I read chapter 13 of Pharo By Example again and again until it makes sense (I still don't have this point click, lol).

+3
source

Yes, I think you understand now ...
When you send ^ super new from class B, you still send a message to class B, it's just a message (super new) ...
So you create an instance of B
Unless, of course, if you defined

 A class>>new ^A basicNew 
0
source

Source: https://habr.com/ru/post/917313/


All Articles