Why aren't static methods considered good OO practice?

34,475

Solution 1

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.

Solution 2

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.

Solution 3

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 they are not useful. Some things just don't lend themselves to objects, and they should not be forced into that mold just for the sake of "purity".

Some people think that things should be "pure", and thus anything "impure" is 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.

Solution 4

Static methods cause tight coupling, which is a violation of good Object Oriented Design. The tight coupling of the calling code and the code within the static method cannot be avoided through Dependency Inversion because static methods inherently don't support object-oriented design techniques such as Inheritance and Polymorphism.

Besides static methods are difficult to test because of these tightly-coupled dependencies, which oftentimes lead to third-party infrastructure that the code depends upon - like a database, and it makes it very difficult to change the behavior without actually going in and changing the code.

Solution 5

Static methods aren't considered good OO practice due to below reasons:

1) Prevents from Re-usability:

Static methods can't be overriden. It can't be used to in interface.

2) Object Lifetime is very long:

Static methods remain in the memory for a log time and its garbage collection takes long time. Developer's don't have control on destroying or creating of Static variables. Excessive usage of static variables can result in the memory overflow.

3) Also, some other points:

It doesn't respect the encapsulation because object does't remain in the complete control of its state. It doesn't follow concepts like Inversion of control, loose coupling, dependency injection, etc.

Share:
34,475
Mike
Author by

Mike

Software Engineering student at the Rochester Institute of Technology. I dig functional programming and simple code.

Updated on July 31, 2022

Comments

  • Mike
    Mike almost 2 years

    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?

  • Mike
    Mike over 13 years
    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.
  • Luis Miguel Serrano
    Luis Miguel Serrano over 13 years
    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.
  • Mike
    Mike over 13 years
    Bear in mind that I never said it was a bad practice, so my question wasn't really answered. ;)
  • Mike
    Mike over 13 years
    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.
  • Eddie
    Eddie over 13 years
    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.
  • Jörg W Mittag
    Jörg W Mittag over 13 years
    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.
  • Jeff Mercado
    Jeff Mercado over 13 years
    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.
  • Adam Robinson
    Adam Robinson over 13 years
    @Jeff: VB.NET also allows this nonsensical behavior.
  • Gabe
    Gabe over 13 years
    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?
  • causa prima
    causa prima over 13 years
    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.
  • Admin
    Admin over 13 years
    @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).
  • ikirachen
    ikirachen almost 6 years
    in short - static methods are OOP tool for procedural programing
  • BillMan
    BillMan over 3 years
    Thank you for your very insightful response.