У меня есть много классов, каждый из которых, реализующие GeneralInterface
и, возможно, дополнительные функциональные интерфейсы:Есть ли способ унифицировать методы, включающие только функциональные интерфейсы в один?
interface GeneralInterface {}
class MyObjectTypeOne implements GeneralInterface { /*...*/}
class MyObjectTypeTwo implements GeneralInterface, InterOne { /*...*/}
class MyObjectTypeThr implements GeneralInterface, InterOne, InterTwo { /*...*/}
У меня есть список, который держит эти MyObjectTypeXXX
экземпляры
class ListHolder {
public static List<GeneralInterface> list = new ArrayList<>();
ListHolder() {
list.add(new MyObjectTypeOne());
list.add(new MyObjectTypeTwo());
list.add(new MyObjectTypeTwo());
// add any number of any of the types
}
}
и 20-40 функциональные интерфейсы. Вот 2 примера:
@FunctionalInterface
public interface InterOne {
boolean onInterOne();
static void iterate() {
for (GeneralInterface obj : ListHolder.list) {
if (obj instanceof InterOne) {
if (((InterOne) obj).onInterOne())
System.out.println("yes");
}
}
}
}
и
@FunctionalInterface
public interface InterTwo {
boolean onInterOne(String string);
static void iterate(String string) {
for (GeneralInterface obj : ListHolder.list) {
if (obj instanceof InterTwo) {
if (((InterTwo) obj).onInterTwo(string))
System.out.println("yes");
}
}
}
}
В разных местах в коде мне нужно вызвать различные iterate
методы:
InterTwo.iterate("S");
InterOne.iterate();
Моя проблема заключается в том, что мне нужно поддерживать iterate
метод для всех функциональных интерфейсов, в то время как они эффективно выполняют одно и то же: проверяя, реализует ли этот объект этот интерфейс (отбрасывает его) и вызывает его только абстрактного метода с данными аргументами.
Есть ли способ, через синтаксис или дизайн, поддерживать только один метод, который делает это? Я знаю, что с отражением есть плохой способ сделать это (я показываю это просто, чтобы показать, что я сделал свое исследование, я не хочу его):
static void iterate(Class<?> clazz, Object arg) {
for (GeneralInterface obj : ListHolder.list) {
if (clazz.isAssignableFrom(obj.getClass())) {
Method[] methods = clazz.getMethods();
Method functional;
for (Method m : methods) {
if (m.getModifiers() == Modifier.ABSTRACT) {
functional = m;
break;
}
}
if ((boolean) functional.invoke(obj, arg)) // cast arg or do some other trick
System.out.println("yes");
}
}
}
В вашем сценарии отражения вы сможете использовать параметры 'Object', чтобы он не был полностью работоспособен, не так ли? Или добавьте приведение в класс параметров, используемых в функциональном методе. –
@YassinHajaj О пути отражения, да, в вызове будет какой-то притвор или какой-нибудь другой трюк. Это не так важно, так как это плохой путь. – user1803551
Не могли бы вы объяснить, какова ваша фактическая проблема, которую вы пытаетесь решить, используя кучу интерфейсов? Кажется, это проблема XY: http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem – krokodilko