I think that using an interface for shared constants is an example of confusing two different concepts:
- Code reuse
- Subtyping
In my experience using subclassing, or interface implementation simply to prevent the duplication of code leads to problems. Your code becomes more fragile. For example, someone might accidental redefine the constant - especially if your class hierarchy is several classes deep.
It is often better to use composition to keep your code DRY.
Another problem with using inheritance in this way is that generally this type of inheritance forms part of the API of your class. The hierarchy of the class is visible outside of the class. This breaks encapsulation. There is no need for you to expose your use of the constants outside of the class, they are to do with how you have chosen to implement your class and are not part of its API (in your example).
This can lead to horrible backwards compatibility problems. Someone else might come along and write code like this:
public interface Constants {
static final int CONST = 2;
}
public class MyClass implements Constants {
int doSomething(int input) {
return CONST * input;
}
}
public class ThirdPartyClass {
int doSomethingElse(int input) {
return MyClass.CONST + input;
}
}
Now, if you decide you no longer need to use CONST in MyClass you are stuck. Because ThirdPartyClass has create a dependency on CONST being available in MyClass.
You can end up with this. Where MyClass is not using any of the constants in the interface, but still has to implement it.
public interface Constants {
static final int CONST = 2;
}
public class MyClass implements Constants {
int doSomething(int input) {
return input;
}
}
public class ThirdPartyClass {
int doSomethingElse(int input) {
return MyClass.CONST + input;
}
}
In short; never do this!