I'm reading Programming Scala. At the beginning of chapter 4, the author comments that Java supports static methods, which are "not-so-pure OO concepts." Why is this so?
Static methods are not so pure OO concepts because they can be invoked without an object actually being associated with them. You use the class itself. You invoke them like this Classname.method(...);
Concept of OO is talks about controlling/accessing data from an object, but static methods need not to be called using an object and they belong to class rather than object.
--Cheers
Don't confuse "not-so-pure OO concepts" with "bad practice". Being "pure OO" is not some panacea that you should attempt to achieve. Just because static methods don't take an instance variable as a parameter does not mean that are not useful. Some things just don't lend themselves to objects, and they should not be forced into that mold just for "purity".
Some people think that things should be "pure", and thus anything "impure" are bad practice. In reality, bad practice is just doing things that are confusing, hard to maintain, difficult to use, etc. Creating static methods that take an instance is bad practice because any method that takes an instance should probably be an instance method. On the other hand, things like utility and factory functions generally don't take an instance, so they should be static.
If you're wondering why they're not "pure OO", it's because they are not instance methods. A "pure" OO language would have everything being an object and all functions be instance methods. Of course, that's not terribly useful all the time. For example, consider the Math.atan2
method. It takes two numbers and doesn't require any state. What object could you even make it a method of? In a "pure" OO language, Math
might itself be an object (a singleton, probably), and atan2
would be an instance method, but since the function doesn't actually use any state in the Math
object, it is also not a "pure OO" concept.
One reason that static methods aren't very OO that hasn't been mentioned so far is that interfaces and abstract classes only define non-static methods. Static methods thus don't fit very well into inheritance.
Note also that static methods do not have access to "super
", which means that static methods cannot be overridden in any real sense. Actually, they can't be overridden at all, only hidden. Try this:
public class Test {
public static int returnValue() {
return 0;
}
public static void main(String[] arg) {
System.out.println(Test.returnValue());
System.out.println(Test2.returnValue());
Test x = new Test2();
System.out.println(x.returnValue());
}
}
public class Test2 extends Test {
public static int returnValue() {
return 1;
}
}
When you run this, you won't get what you expect. Test.returnValue()
gives what you expect. Test2.returnValue()
hides the method of the same name in the superclass (it does not override it), and it gives what you would expect.
One might naively expect "non-statically" calling a static method to use polymorphism. It doesn't. Whatever class the variable is declared as is the one used to look up the method. This is bad form because someone might expect the code to do something different from what it actually does.
This doesn't mean, "Don't use static methods!" It does mean that you should reserve use of static methods for those instances where you really want the Class object to own the method, and not just as a lazy way of making a singleton.
Object-orientation is about three things:
- messaging,
- local retention and protection and hiding of state-process, and
- extreme late-binding of all things.
Of those three, the most important one is messaging.
Static methods violate at least messaging and late-binding.
The idea of messaging means that in OO, computation is performed by networks of self-contained objects which send messages to each other. Sending a message is the only way of communication/computation.
Static methods don't do that. They aren't associated with any object. They really aren't methods at all, according to the usual definition. They are really just procedures. There's pretty much no difference between a Java static method Foo.bar
and a BASIC subroutine FOO_BAR
.
As for late-binding: a more modern name for that is dynamic dispatch. Static methods violate that, too, in fact, it's even in their very name: static methods.
Static methods break some very nice properties of object-orientation. For example, object-oriented systems are automatically capability-safe with objects acting as capabilities. Static methods (or really any statics, be that static state or static methods) break that property.
You can also execute every object in parallel in its own process, since they only communicate via messaging, thus providing some trivial concurrency. (Like Actors, basically, which shouldn't be too surprising, since Carl Hewitt created the Actor Model based on Smalltalk-71, and Alan Kay created Smalltalk-71 partially based on PLANNER, which in turn was created by Carl Hewitt. The close relationship between actors and objects is far from coincidental, in fact, they are essentially one and the same.) Again, statics (both static methods, and especially static state) break that nice property.