Does it make sense to have a non static method which does not use an instance variable?
Asked Answered
A

7

31

The compiler does not let a static method call a non static method. I understand it does this because a not static method usually ends up using an instance variable.

But does it make sense to have a non static method which does not use an instance variable. If we have a behavior which does not affect or isn't affected by the instance state , shouldn't such a method be marked as static.

Ankeny answered 4/8, 2015 at 16:10 Comment(0)
B
26

Often times, no. If the method doesn't touch any instance state, there's no reason to tie it to an instance.

Of course, static methods can't be inherited or overridden, so that's one obvious time that you would want to have an instance method that doesn't use instance state. The strategy pattern is a classic example of this.

Another case where you may tie it to an instance anyway is if this is a public API and you imagine that you may want to tie the method to instance state in the future. In that case, backwards compatibility concerns for people who are using your API may make it difficult (or impossible) to turn that static method into an instance method.

Boldface answered 4/8, 2015 at 16:18 Comment(2)
The API argument is the most important point here. A static method cannot implement methods from inherited interfaces. A static method is not subject to polymorphism. static methods are in fact very limited as to their capabilities.Cuenca
@BoristheSpider Of course, that's both a blessing and a curse. Many functional languages build heavily on "static" functions - basically, anything that doesn't explicitly have to be tied to an instance (e.g. polymorphic interface implementations) will tend to be static. In some ways it's a return to the old-school C days, but it's quite refreshing. Since functional programming tends to favour composition over inheritance rather heavily, this makes perfect sense.Southland
C
30

Well sure! Let's assume that you have in interface IMyCollection. It has a method boolean isMutable().

Now you have two classes, class MyMutableList and class MyImmutableList, which both implement IMyCollection. Each of them would override the instance method isMutable(), with MyMutableList simply returning true and MyImmutableList returning false.

isMutable() in both classes is an instance method that (1) does not use instance variables, and (2) does not affect instance state. However, due to constraints in the language (it's impossible to override static methods), this design is the only practical one.

Also, I would like to clear up a misconception (as @manouti did as well): non-static methods aren't instance because they use any instance variables or affect instance state; they're instance methods because they were defined that way (without the static keyword), and thus have an implicit this parameter (which, in languages like Python, is actually explicit!).

Cespitose answered 4/8, 2015 at 16:18 Comment(0)
B
26

Often times, no. If the method doesn't touch any instance state, there's no reason to tie it to an instance.

Of course, static methods can't be inherited or overridden, so that's one obvious time that you would want to have an instance method that doesn't use instance state. The strategy pattern is a classic example of this.

Another case where you may tie it to an instance anyway is if this is a public API and you imagine that you may want to tie the method to instance state in the future. In that case, backwards compatibility concerns for people who are using your API may make it difficult (or impossible) to turn that static method into an instance method.

Boldface answered 4/8, 2015 at 16:18 Comment(2)
The API argument is the most important point here. A static method cannot implement methods from inherited interfaces. A static method is not subject to polymorphism. static methods are in fact very limited as to their capabilities.Cuenca
@BoristheSpider Of course, that's both a blessing and a curse. Many functional languages build heavily on "static" functions - basically, anything that doesn't explicitly have to be tied to an instance (e.g. polymorphic interface implementations) will tend to be static. In some ways it's a return to the old-school C days, but it's quite refreshing. Since functional programming tends to favour composition over inheritance rather heavily, this makes perfect sense.Southland
C
8

Because static methods cannot be overridden, many developers that are concerned about testability of their code try to avoid static methods in Java altogether.

Code is more testable if dependencies can be replaced with mock objects. Mockito and EasyMock are the most common tools to help with this, and they rely on inheritance to create subclasses that allow you to easily override the (often complex) method that you don't want to test ... so that your test is focused on what you do want to test.

I don't go to the extreme of trying for zero static methods, but when I concede to include them, I often regret it later, for testing reasons.

All of this is very frustrating, because it has nothing to do with what ought to be the design consideration of static vs instance methods. Which makes me wish for those languages that allow you have have functions that aren't connected with a class ...

Calvities answered 4/8, 2015 at 17:25 Comment(0)
J
8

If one were writing a human-readable description of the method's purpose, would it make mention of an object? If so, use an instance method. If not, use a static method. Note that some methods might be described either way, in which case one should use judgment about which meaning is better.

Consider, for example, "Get the address to which a Freedonian income tax form should be mailed" vs "Get the address to which Freedonian income tax forms should be mailed"? The first question should be answered by an instance method; the second by a static method. It may be that Freedonia presently requires all tax forms to be sent to the same address (in which case the former method might ignore all instance fields), but in future may have different offices for people in different regions (in which case the former method might look at the taxpayer ID and select a mailing address based upon that, while the latter method would have to direct forms to an office which could accept forms for anyone and redirect them as needed).

Jumada answered 4/8, 2015 at 18:27 Comment(0)
S
3

I understand it does this because a not static method usually ends up using an instance variable.

Even if the instance method does not use an instance variable, it is still bound to the instance of the class. In fact, it has a reference to this implicitly in the method arguments.

In other words, in the following method:

public void foo() {

}

this is implicitly passed as the first local variable in the method.

EDIT:

Re-reading the question, it's more of a broad question that depends on the situation. Generally if the method does not need the instance (and you're pretty sure it won't), then just make it static.

Spock answered 4/8, 2015 at 16:12 Comment(4)
i understand. But do we in real applications write such instance methods (that is independent of instance variables)Ankeny
@Twister This is a different problem. Here you're considering logical decisions made by the programmer on whether the method should be static or not. The compiler does not care about this: it has to enforce the rules.Spock
And this answer question how ?Unrefined
@Twister Let's say you need to filter some input arguments by some static (hardcoded) rules. And the same filter has to be applied in several methods of your class. That's a static candidate in real life.Plash
M
2

A nice example is an object-oriented encoding of booleans. Most languages, even object-oriented ones like Java, opt for an Abstract-Data-Type-oriented encoding of booleans, but e.g. Smalltalk uses an OO encoding, and almost none of the methods make use of any instance state. It looks a bit like this:

import java.util.function.Supplier;
@FunctionalInterface interface Block { void call(); }

interface Bool {
  Bool not();
  Bool and(Bool other);
  Bool or(Bool other);
  <T> T ifThenElse(Supplier<T> thenBranch, Supplier<T> elseBranch);
  void ifThenElse(Block thenBranch, Block elseBranch);

  static final Bool T = new TrueClass();
  static final Bool F = new FalseClass();

  class TrueClass implements Bool {
    public Bool not() { return F; }
    public Bool and(Bool other) { return other; }
    public Bool or(Bool other) { return this; }
    public <T> T ifThenElse(Supplier<T> thenBranch, Supplier<T> elseBranch) {
      return thenBranch.get();
    }
    public void ifThenElse(Block thenBranch, Block elseBranch) {
      thenBranch.call();
    }
  }

  class FalseClass implements Bool {
    public Bool not() { return T; }
    public Bool and(Bool other) { return this; }
    public Bool or(Bool other) { return other; }
    public <T> T ifThenElse(Supplier<T> thenBranch, Supplier<T> elseBranch) {
      return elseBranch.get();
    }
    public void ifThenElse(Block thenBranch, Block elseBranch) {
      elseBranch.call();
    }
  }
}

public class Main {
  public static void main(String... args) {
    Bool.F.ifThenElse(() -> System.out.println("True"), () -> System.out.println("False"));
    // False
  }
}

In fact, if you follow a serious commitment to OO, use a lot of referentially transparent methods, and favor polymorphism over conditionals, you will often end up with methods in lots of subclasses, where each implementation in one of the classes returns a constant value.

Mandeville answered 4/8, 2015 at 19:34 Comment(0)
A
2

I think sometimes it is yes,because non static method can override to do different tasks for different class,but the task may not involve instance variable,e.g.:

Fruit.java

public class Fruit{
    public void printInfo(){
        System.out.println("This is fruit");
    }
}

Orange.java

public class Orange extends Fruit{
    public void printInfo(){
        System.out.println("This is orange");
    }
}

Grape.java

public class Grape extends Fruit{
    public void printInfo(){
        System.out.println("This is grape");
    }
}

print info of object:

Fruit f=new Grape();
f.printInfo();
Ascensive answered 5/8, 2015 at 4:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.