Что вы действительно хотите сделать, так это удалить объявление enum из вашего класса "ThingImpl" и переместить все его (включая его конструктор и геттеры) в интерфейс Thing.
Сделайте ваши поля окончательными в перечислении, чтобы помнить, что их не следует трогать.
Таким образом, все, кто хочет использовать интерфейс Thing, должен использовать перечисление, определенное в вашем интерфейсе - ваша проблема в том, что вы фактически определяете его дважды, но оно должно быть либо в интерфейсе (что хорошо, если это будет только для этого интерфейса) или в качестве файла Java перечисления общедоступного уровня (с использованием общедоступного перечисления вместо общедоступного класса). Вы бы сделали это общедоступным перечислением, если разумно ожидать, что его будет использовать что-то другое, кроме вашего интерфейса - Map.Entry, на мой взгляд, является плохо вложенным интерфейсом, потому что другие классы используют пару ключ / значение, внешнюю по отношению к карте, и таким образом, это должен быть собственный интерфейс, но мы должны жить с ним: (
Идея состоит в том, чтобы MovingState в ThingImpl расширял MovingState из интерфейса Thing (таким образом, отделяя фактическую реализацию MovingState от интерфейса).
Я не думаю, что это действительно ваша идея - я думаю, что поведение, которое вы указали в интерфейсе Thing, в порядке, вы действительно не хотите трогать перечисление MovingState, поскольку оно в порядке. Однако если вы считаете, что что-то требует другой реализации MovingState, вы можете заставить его реализовать интерфейс с именем MovingState и, таким образом, вы можете переименовать свой enum DefaultMovingState. Это твой выбор.
Ваш интерфейс MovingState будет просто иметь геттеры, которые вы выставляете в MovingState прямо сейчас. Два метода.