This was a design decision made by Sun when creating the
Java language. It was not that Interfaces couldn't have been made to support non-final variables, but rather that it was deemed inappropriate to support non-final variables.
Since I wasn't there when the decision was made, I couldn't possibly give you a sure answer, but I can speculate, and there are some pretty good reasons that certainly support thier decision.
One of the goals of Object-Oriented programming is encapsulation. An object is typically seens as providing a public interface (with a small 'i'), and an implementation. The interface describes what the object is capable of doing, and provides a list of methods (including thier signatures) that a client can use to cause the object to perform the functions of said object. The implementation is the manner in which the object actually goes about doing it's tasks.
Now, there is a very good reason for separating the interface from the implementation. If two objects have the same public interface (that is, they both declare that they are capable of performing the same set of tasks), then theoretically, either one of the two objects could be selected at runtime to perform one of the tasks, and the task will be performed. The difference is sometimes efficiency and power, other times it is to produce different side effects, or to use a different gui to guide the client through the process, etc.
Now, to explain your question. In order to ensure that two objects provide the same public interface, their implementation details should be hidden and inaccessable to clients. If one implementation defines a helper method foo() and the other does not, and the client attempts to call foo(), then they could not switch implementations at run-time. Hence, foo() needs to be private. The same can be said about variables. Most people feel that varibles are basically always an implementation detail, because they don't describe what the objects can do, but rather, they describe how data is stored by the implementation.
The creators of Java created the Interface (with a capital 'i') construct to allow developers to define a Type which declares a public interface, that is, a list of things that it can do. This is important because java is a strongly typed language, so you need to be able to refer to any implementation of an interface by the same type. The Interface is designed to present ONLY the public interface of a class. Hence, all methods are public and abstract, and all variables are coderanch, static, and final.
Both methods and variables must be public because the point of an Interface is to provide a way for the client to interact with the object. If the methods and variables were not coderanch, the clients would not have access to them. If you then forced any class implementing that Interface to declare those non-public methods, they would either have to provide empty implementations of those methods, or else they would have to factor them into the design of their implementation. Hence, the Interface would be encroaching on the domain of implementation.
Methods need to be abstract simply because HOW those methods are written is an implementation detail. Making the methods abstract ensures that no code is written in the method as defined in the interface, because that would also encroach on the domain of implementation. Interfaces should only say WHAT classes can do, not HOW they do it.
Finally, we come to the restriction that variables must be static and final. The reason for this is because if they are static, then they belong to the interface, and not the object, nor the run-time type of the object. They are also final, because if the implementation was allowed to change their values, then they would become a part of the implementation, and not the interface.
Usually, the purpose of defining constants in Interfaces is to provide canned return values for methods, or to provide resources that would be needed for any implementation. For example, one could enumerate the list of possible results to a method, as one might do in a Finite State Machine.
Using constants for other reasons in an Interface is typically a violation of encapsulation, and should be avoided. For example:
In this case, defining BETA in the Interface is a violation of encapsulation, becuase BETA is used in one possible method of calculating the diagonal of a square, but not in all methods. For example, the diagonal length of a square can be calculated using the pythagorean theorem using the single side lenght for both
a and
b in the formula
a� +
b� =
c�. This method never uses BETA, because BETA is an implementation detail of a different implementation. Hence, although it is allowed by java, it is a violation of encapsulation.
Typically, before you define a variable in an interface, be sure that it is required by all POSSIBLE implementations (i.e. it is part of an enumeration of possible return values of a method, etc).
- Adam
[ July 31, 2006: Message edited by: Adam Nace ]
[ July 31, 2006: Message edited by: Adam Nace ]