Это похоже на типичный вариант использования enum
.Константы enum
могут иметь тело класса с кодом, переопределяя методы базового типа и даже объявлять новые поля.
Задача получения экземпляра всех подтипов подразумевает закрытый набор подтипов,что соответствует поведению enum
типов.
public enum Letter {
A {
@Override
public boolean isVowel() {
return true;
}
},
B, C, D,
E {
@Override
public boolean isVowel() {
return true;
}
},
F, G, H,
I {
@Override
public boolean isVowel() {
return true;
}
}, J, K, L, M, N,
O {
@Override
public boolean isVowel() {
return true;
}
}, P, Q, R, S, T,
U {
@Override
public boolean isVowel() {
return true;
}
}, V, W, X, Y, Z;
;
String letter = name();
public static List<Letter> getLetters() {
return Arrays.asList(values());
}
public boolean isVowel() {
return false;
}
}
Это демонстрирует, что переопределение методов возможно, а также метод для получения всех экземпляров (в виде массива) предоставляется бесплатно.Кроме того, имена задаются по своей сути без избыточности.
Если вы хотите иметь вместо этого открытый набор подклассов, который может быть расширен после компиляции кода, вам следует взглянуть на концепцию Service Provider и ServiceLoader
класс.Этот механизм не будет автоматически находить подклассы, а только те, которые объявлены в качестве поставщиков услуг либо в файле в META-INF
, либо через декларацию модуля, с другой стороны, он предоставляет вам надежное, устоявшееся решение, которое будет поддерживаться разработчиками Javaили даже развиваться вместе с платформой, как интеграция в концепцию новых модулей.