views:

2311

answers:

9

The topic says the most of it - what is the reason for the fact that static methods can't be declared in an interface?

public interface ITest {
    public static String test();
}

The code above gives me the following error (in Eclipse, at least): "Illegal modifier for the interface method ITest.test(); only public & abstract are permitted".

+5  A: 

Static methods are not instance methods. There's no instance context, therefore to implement it from the interface makes little sense.

Ryan Farley
+5  A: 

I'll answer your question with an example. Suppose we had a Math class with a static method add. You would call this method like so:

Math.add(2, 3);

If Math were an interface instead of a class, it could not have any defined functions. As such, saying something like Math.add(2, 3) makes no sense.

Kyle Cronin
+6  A: 

The reason why you can't have a static method in an interface lies in the way Java resolves static references. Java will not bother looking for an instance of a class when attempting to execute a static method. This is because static methods are not instance dependent and hence can be executed straight from the class file. Given that all methods in an interface are abstract, the VM would have to look for a particular implementation of the interface in order to find the code behind the static method so that it could be executed. This then contradicts how static method resolution works and would introduce an inconsistency into the language.

Espo
This explanation doesn't explain the problem. Every interface have it's own class-file, it could contain the static-method. So no lookup for a particular implementation would be needed.
Mnementh
Not every interface type in Java is within it's own file, nor should it be according to JLS. Additionally JLS doesn't stipulate that classes have to be always stored withing a file system, quite the contrary.
Totophil
+3  A: 

Static methods are class methods. In Java, strictly speaking, an interface is not a class. Also, static methods can not be overridden.

wilhelmtell
+3  A: 

An interface is used for polymorphism, which applies to Objects, not types. Therefore (as already noted) it makes no sense to have an static interface member.

Rob Cooper
+1  A: 

Perhaps a code example would help, I'm going to use C#, but you should be able to follow along.

Lets pretend we have an interface called IPayable

public interface IPayable
{
    public Pay(double amount);
}

Now, we have two concrete classes that implement this interface:

public class BusinessAccount : IPayable
{
    public void Pay(double amount)
    {
     //Logic
    }
}

public class CustomerAccount : IPayable
{
    public void Pay(double amount)
    {
     //Logic
    }
}

Now, lets pretend we have a collection of various accounts, to do this we will use a generic list of the type IPayable

List<IPayable> accountsToPay = new List<IPayable>();
accountsToPay.add(new CustomerAccount());
accountsToPay.add(new BusinessAccount());

Now, we want to pay $50.00 to all those accounts:

foreach (IPayable account in accountsToPay)
{
    account.Pay(50.00);
}

So now you see how interfaces are incredibly useful.

They are used on instantiated objects only. Not on static classes.

If you had made pay static, when looping through the IPayable's in accountsToPay there would be no way to figure out if it should call pay on BusinessAcount or CustomerAccount.

FlySwat
+9  A: 

There are a few issues at play here. The first is the issue of declaring a static method without defining it. This is the difference between

public interface Foo {
  public static int bar();
end

and

public interface Foo {
  public static int bar() {
    ...
  }
}

Java doesn't allow either, but it could allow the second. The first is impossible for the reasons that Espo mentions: you don't know which implementing class is the correct definition.

Java could allow the latter, as long as it treated Interfaces as first-class Objects. Ruby's Modules, which are approximately equivalent to Java's Interfaces, allow exactly that:

module Foo
  def self.bar
    ...
  end
end
James A. Rosen
+3  A: 

The reason lies in the design-principle, that java does not allow multiple inheritance. The problem with multiple inheritance can be illustrated by the following example:

public class A {
   public method x() {...}
}
public class B {
   public method x() {...}
}
public class C extends A, B { ... }

Now what happens if you call C.x()? Will be A.x() or B.x() executed? Every language with multiple inheritance has to solve this problem.

Interfaces allow in Java some sort of restricted multiple inheritance. To avoid the problem above, they are not allowed to have methods. If we look at the same problem with interfaces and static methods:

public interface A {
   public static method x() {...}
}
public interface B {
   public static method x() {...}
}
public class C implements A, B { ... }

Same problem here, what happen if you call C.x()?

Mnementh
+2  A: 

There's a very nice and concise answer to your question here. (It struck me as such a nicely straightforward way of explaining it that I want to link it from here.)

Zarkonnen