Lazycoder

20May/085

Why can’t you declare a static method in an interface?

I've stated on Twitter a couple of times that I'd like to be able to declare static methods as part of my interface. My reasoning is: If an interface defines a contract in my code, why can't a static method be part of that contract?

CODE:
  1. public interface ITryStatic {
  2.     static void Foo();
  3.     void Bar();
  4. }

I found a great answer over in this forum.

In both Java and .NET, classes can only inherit from one class but a class can implement multiple interfaces. So consider the following code.

CODE:
  1. public interface ITryStatic {
  2.     static void Foo();
  3. }
  4.  
  5. public interface ITryAnotherStatic {
  6.     static void Foo();
  7. }
  8.  
  9.  
  10. public class Whoops : ITryStatic, ITryAnotherStatic {
  11.     public static void Foo() { printline("Foo"); }
  12. }
  13.  
  14. ITryStatic staticWhoops;
  15. staticWhoops.Foo(); //which one does it try? It doesn't matter since there's no code to run.
  16. ((Whoops)staticWhoops).Foo(); //Sure, but it defeats the purpose of using an interface.

Essentially the answer is: The compiler tries to run the code specified by the static method in a class. Since an interface doesn't provide an implementation details, there is nothing to run. You could, if the compiler would let you, cast the interface to the concrete type that's actually being represented. But that defeats the purpose of declaring an using an interface.

I do wonder if type inference could be used to route around this problem?

  • Steve F

    I would still like to see this feature even if it required explicit interface implementation.

    I often find myself creating pointless wrappers just so I can expose a static method or property to an interface.

  • http://weblog.raganwald.com/ Reg Braithwaite

    Consider two classes, A and B where A extends B, and both define static foo(). If you write:

    A someB = new B();
    someB.foo();

    The compiler always executes A.foo() and not B.foo(): static methods are NOT polymorphic, the compiler invokes the method of the declared class and not the runtime class of the object, which is one of the reasons invoking a static method on an instance is often eschewed as producing unclear code: it may not do what the reader thinks it does.

    So my answer is that static methods in an interface could be accommodated by placing the implementation of the method in the interface. Before you shout me down that code doesn’t belong in an interface, remember that the instance methods declared in an interface can be overridden.

    That’s the point of polymorphism. But static methods cannot be overridden, so they are useful for declaring invariants. For example, you could use this to declare a static method that defines how to compare two ITryStatics for equality.

  • Sean

    It wouldn’t really make sense to be able to define a public member of any kind in an interface. An interface is a data contract for an object instance. A static method is not part of an instance, and would therefore not be part of a contract.

    What is so special about this hypothetical static method that it can’t be a non-static member, and part of the interface implementation? Alternatively, why couldn’t the static method be encapsulated in some other class, perhaps a static helper class? What is the benefit of encapsulating a static member in an interface, and what is the drawback of adhering to the .NET and Java specifications?

  • http://www.lazycoder.com Scott

    Sean: There could be some methods, like a static “IMyClass GetInstance(int keyId)”, that would return an instance of the class implementing the interface that I might want to specify in a contract. So if I’m injecting into another class that will obtain a reference to the class implementing the interface I’d need a static method.

  • http://www.dynconcepts.com David V. Corbin

    Reg Braithwaite,

    Static methods are indended to be bound to a TYPE. They should not EVER be considered Polymorphic. PERIOD.

    If you want something to change depending on what an INSTANCE is, then it should be a member OF THAT INSTANCE.

    This is one of the key deciding factors when determining if BEHAVIOR is bound to a specific TYPE or to what a SPECIFIC instance happens to be at the time.