Я думаю, что использование интерфейса для общих констант является примером смешения двух разных концепций:
- Повторное использование кода
- подтип
По моему опыту, использование подклассов или реализация интерфейса просто для предотвращения дублирования кода приводит к проблемам. Ваш код становится более хрупким. Например, кто-то может случайно переопределить константу, особенно если ваша иерархия классов имеет несколько классов.
Часто лучше использовать композицию, чтобы сохранить код сухим.
Другая проблема с использованием наследования таким способом заключается в том, что обычно этот тип наследования является частью API вашего класса. Иерархия класса видна за пределами класса. Это нарушает инкапсуляцию. Вам не нужно показывать использование вами констант вне класса, они связаны с тем, как вы решили реализовать свой класс, и не являются частью его API (в вашем примере).
Это может привести к ужасным проблемам обратной совместимости. Кто-то может прийти и написать код, подобный этому:
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;
}
}
Теперь, если вы решите, что вам больше не нужно использовать CONST в MyClass, вы застряли. Потому что ThirdPartyClass создает зависимость от CONST, доступного в MyClass.
Вы можете закончить с этим. Где MyClass не использует какие-либо константы в интерфейсе, но все еще должен реализовать это.
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;
}
}
Короче говоря; никогда не делай этого!