ich viele Klassen haben, die jeweils Umsetzung GeneralInterface
und möglicherweise zusätzliche funktionale Schnittstellen:Gibt es eine Möglichkeit, Methoden mit nur funktionalen Schnittstellen zu einer zu vereinheitlichen?
interface GeneralInterface {}
class MyObjectTypeOne implements GeneralInterface { /*...*/}
class MyObjectTypeTwo implements GeneralInterface, InterOne { /*...*/}
class MyObjectTypeThr implements GeneralInterface, InterOne, InterTwo { /*...*/}
Ich habe eine Liste, die diese MyObjectTypeXXX
Instanzen
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
}
}
und 20-40 funktionalen Schnittstellen hält. Hier sind zwei Beispiele:
@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");
}
}
}
}
und
@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");
}
}
}
}
An verschiedenen Stellen im Code muss ich verschiedene iterate
Methoden aufrufen:
InterTwo.iterate("S");
InterOne.iterate();
Mein Problem ist, dass ich das halten iterate
Methode für alle funktionalen Schnittstellen, während sie effektiv dasselbe tun: Überprüfen, ob das Objekt diese Schnittstelle implementiert, (Casting) und nur aufrufen abstrakte Methode mit den gegebenen Argumenten.
Gibt es einen Weg, über Syntax oder Design, nur 1 Methode, die das tut? Ich weiß, dass mit Reflexion es eine schlechte Art und Weise ist, dies zu tun (ich bin zeigt es nur um zu zeigen, dass ich meine Forschung tat, ich will es nicht):
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");
}
}
}
In Ihrem Reflektionsszenario können Sie nur 'Object' Parameter verwenden, so dass es nicht perfekt funktioniert, irre ich mich? Oder fügen Sie der Parameterklasse, die in der funktionalen Methode verwendet wird, einen Cast hinzu. –
@YassinHajaj Über den Reflexionsweg, ja, es wird entweder eine Besetzung im Aufruf oder ein anderer Trick sein. Es ist nicht so wichtig, da es sowieso ein schlechter Weg ist. – user1803551
Können Sie erklären, was Ihr eigentliches Problem ist, das Sie mit einer Reihe von Schnittstellen lösen möchten? Es scheint ein XY-Problem zu sein: http://meta.stackexchange.com/questions/66377/what-is-the-xy-problem – krokodilko