I am trying to work around the issue with JAVA overloading, here is a testing code:
public class Main {
static interface Base {
void func(Base o);
}
static interface ExtBase extends Base {
void func(ExtBase o);
}
static class BaseClass implements Base {
public void func(Base o) {
System.out.println("Method:BaseClass#func(Base)");
System.out.println("Real Class:" + this.getClass().getCanonicalName() + " | Real Object:" + o.getClass().getCanonicalName() + "\n");
}
}
static class ExtBaseClass extends BaseClass implements ExtBase {
public void func(ExtBase o) {
System.out.println("Method:ExtBaseClass#func(ExtBase)");
System.out.println("Real Class:" + this.getClass().getCanonicalName() + " | Real Object:" + o.getClass().getCanonicalName() + "\n");
}
}
static class OverrideExtBaseClass extends BaseClass implements ExtBase {
public void func(Base o) {
System.out.println("Method:ExtBaseClass#func(Base)");
System.out.println("Real Class:" + this.getClass().getCanonicalName() + " | Real Object:" + o.getClass().getCanonicalName() + "\n");
}
public void func(ExtBase o) {
System.out.println("Method:ExtBaseClass#func(ExtBase)");
System.out.println("Real Class:" + this.getClass().getCanonicalName() + " | Real Object:" + o.getClass().getCanonicalName() + "\n");
}
}
public static void main(String[] args) {
ExtBase a = new ExtBaseClass();
a.func(a);
Base b = new ExtBaseClass();
b.func(b);
Base c = new OverrideExtBaseClass();
c.func(c);
List<Base> list = new ArrayList<>();
list.add(a);
list.add(b);
list.add(c);
for (Base d : list) {
d.func(d);
}
for (Base d : list) {
try {
d.getClass().getMethod("func", d.getClass().getInterfaces()[0]).invoke(d, d);
} catch (IllegalAccessException | IllegalArgumentException | NoSuchMethodException | SecurityException | InvocationTargetException e) {
e.printStackTrace();
}
}
}
}
If we look at the outputs:
ExtBase a = new ExtBaseClass();
a.func(a);
// Method:ExtBaseClass#func(ExtBase)
// Real Class:Main.ExtBaseClass | Real Object:Main.ExtBaseClass
This is all good, just a control test.
Base b = new ExtBaseClass();
b.func(b);
// Method:BaseClass#func(Base)
// Real Class:Main.ExtBaseClass | Real Object:Main.ExtBaseClass
Here I have an overloading issue. Even though the real classes are identified as ExtBaseClass, it is still calling the method BaseClass#func(Base)...
Base c = new OverrideExtBaseClass();
c.func(c);
// Method:ExtBaseClass#func(Base)
// Real Class:Main.OverrideExtBaseClass | Real Object:Main.OverrideExtBaseClass
OK, at least the overriding works, the ExtBaseClass method is called, but still it is the func(Base) version, not the func(ExtBase) version...
This is causing me trouble because I have a list of the Base class objects and try to loop through them and call the appropriate version of func
for each of them.
List<Base> list = new ArrayList<>();
list.add(a);
list.add(b);
list.add(c);
for (Base d : list) {
d.func(d);
}
// Method:BaseClass#func(Base)
// Real Class:Main.ExtBaseClass | Real Object:Main.ExtBaseClass
// Method:BaseClass#func(Base)
// Real Class:Main.ExtBaseClass | Real Object:Main.ExtBaseClass
// Method:ExtBaseClass#func(Base)
// Real Class:Main.OverrideExtBaseClass | Real Object:Main.OverrideExtBaseClass
See how none of these are calling the func(ExtBase) version...I can't change this to List<ExtBase>
because I may have other interfaces extending Base in the list.
I need a way to work around this JAVA limitation. I wouldn't mind using reflection like
d.getClass().getMethod("func", d.getClass().getInterfaces()[0]).invoke(d, d);
which gives me my expected outputs:
// Method:ExtBaseClass#func(ExtBase)
// Real Class:Main.ExtBaseClass | Real Object:Main.ExtBaseClass
// Method:ExtBaseClass#func(ExtBase)
// Real Class:Main.ExtBaseClass | Real Object:Main.ExtBaseClass
// Method:ExtBaseClass#func(ExtBase)
// Real Class:Main.OverrideExtBaseClass | Real Object:Main.OverrideExtBaseClass
Is there a cleaner or more correct way to work around the issue if not using reflection?
Aucun commentaire:
Enregistrer un commentaire