Reputation: 2262
I noticed in ProfStef's tutorial sometimes messages are sent to classes instead of objects. I know that classes are also objects but how can a class look up a method if I didn't create an instance of the class first? Are those methods defined at class level? Something similar to Java's static methods?
Upvotes: 2
Views: 334
Reputation: 3141
As you have noted, every class is an object, too. If you evaluate and inspect Object
you will see it. You can also look up the class of a class: Object class
. It is an instance of Metaclass
, which has a method dictionary like any other Behavior, and therefore its instances (i. e. the class objects) can respond to messages.
In the System Browser when you look at a class, you can switch the view between the instance methods and the class methods. The messages on the class side you can send directly to the class.
Static methods in Java bear a resemblance to class methods in Smalltalk, but they are not exactly the same. For example, you cannot override static methods in Java. In Smalltalk you can override a class method in a subclass. You will see some classes in the system overriding new
. This works because the metaclasses inherit from each other just like the regular classes. The metaclass hierarchy is parallel to the class hierarchy: Collection
is a subclass of Object
, and Collection class
is a subclass of Object class
. Therefore, Collection class methods can override Object class methods. In Java you cannot rely on polymorphism among static methods.
For example, what would you expect this to print:
public class Main {
public static void main(String[] args) {
B.foo();
}
}
class A {
public static void foo() {
System.out.println(bar());
}
public static String bar() {
return "A";
}
}
class B extends A {
public static String bar() {
return "B";
}
}
It will print "A". The invocation of bar()
in A.foo is hardwired to A.bar.
If you write the same in Smalltalk with class methods, the message send self bar
in A.foo would be dispatched by the metaclass of B since you sent the foo message to B. Since B class redefines the method bar
like above, it would instead call the class method of B, not the class method of A, and therefore print "B".
One more symptom of this difference is that you cannot use this
in a static method in Java.
Upvotes: 5