views:

144

answers:

6

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?

+1  A: 

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(...);

Luis Miguel
What if I am using something like Ruby, which supports classes-as-objects and static invocation? An object would in fact be associated with the static call.
Mike
Well I'm not sure how associated to Java the author was when he said what he did, but thing is that even in Java there are objects that are created and managed to represent the classes themselves too, so this is all a bit discussable, to some extent. However, the simple idea that you have a static main method, and static methods you can invoke without having any objects makes it be a bit against the OOP paradigm.
Luis Miguel
A: 

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

Koteswara sarma
+4  A: 

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.

Gabe
Bear in mind that I never said it was a bad practice, so my question wasn't really answered. ;)
Mike
True. On the other hand, I've seen too much code where everything is a singleton and everything is static. This kind of code is usually more difficult to modify, more difficult to extend, more difficult to remold to do something it wasn't originally intended to do. That said, too many people are way too dogmatic about this.
Eddie
Actually, the `atan2` function measures the radians of the angle of a *single point* to the positive x-axis. In other words, it shouldn't take two number arguments in the first place, it should take a single point argument. Which, in OO terms, could be modeled as a method on a point object.
Jörg W Mittag
Jorg: What about the `stdev` and `average` functions? Should those be methods of `Array`? Or should they be instance methods of their own class (`Stats`) that holds all the numbers such that you have to convert your `Array` to a `Stats` so you can average them? Or should they be static methods that you simply pass an array of numbers to?
Gabe
I fully agree. An awful lot of utility functions simply have no OO in their nature. You can shoehorn them into an OO language but all you're doing is adding inefficiency.
Loren Pechtel
+4  A: 

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.

Eddie
This answer probably tends to make the most sense out of what I have seen so far. Breaking one of the trinity concepts certainly goes against the grain.
Mike
Not that I'm disputing this but the example you show only applies to Java right? IIRC, Java is the only OO language (that I have encountered) that allows calling static functions via an instance of the class.
Jeff M
@Jeff: VB.NET also allows this nonsensical behavior.
Adam Robinson
@Adam: Ah, I guess I'm lucky I haven't done much OO programming in VB then. :)
Jeff M
@Jeff: C++ and Python both allow it. It's not as nonsensical you might think, though it is, of course, confusing sometimes (like any feature).
Roger Pate
A: 

Here's a great read:

CoolAJ86
Indeed a good read, but a bit dogmatic. Global state is not the end-all-be-all of evil. Too much use of global state leads to code that is difficult to maintain, but trying to entirely avoid global state can make code convoluted and difficult. Basically, balance is what is important.
Eddie
+3  A: 

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.

Jörg W Mittag
This is also an excellent answer. Wish I could accept more than one. Thank you.
Mike