I have two interfaces in Java (version 8) which are very similar. I cannot change the interfaces and cannot change the classes which implement them.
public interface A {
int get();
}
public interface B {
int get();
int somethingelse();
}
Now I have a function that its implementation fits both interfaces (almost). I want it to do something like that:
public int foo((A | B) p) {
int ret = 0;
if (p instanceof B) {
ret = p.somthingelse();
}
return ret + p.get();
}
I don't want to use inspection because this function is on the main pipeline of my program. I want it to have good performance. Is it possible to do this in Java?
A simple solution will be to copy/paste foo()
and implement it differently for each interface.
But in reality foo()
and the interfaces are much longer than that and I'm trying to avoid code duplication.
Yes, you can pass Interface as a parameter in the function.
Yes, it is mandatory to implement all the methods in a class that implements an interface until and unless that class is declared as an abstract class.
No, every class should not have an interface. It's overkill squared. You use an interface when you need to abstract what's done from how it's done, and you're certain that the implementation can change.
There's unfortunately no way to create that kind of retroactive relationship between two unrelated types.
If you can change foo()
and its invocations, you could be able to make use of functional interfaces matching the signatures that you invoke inside foo
. I'm using IntSupplier
here, with corresponding lambda expressions using concrete implementations of A
and B
.
Say you have these implementations:
class AImpl implements A {
//implementation
}
class BImpl implements B {
//implementation
}
You can change foo
to something like:
public int foo(IntSupplier get, IntSupplier somethingElse) {
int ret = 0;
if (somethingElse != null) {
ret = somethingElse.getAsInt();
}
return ret + get.getAsInt();
}
And call it this way:
A a = new AImpl();
B b = new BImpl();
int result = this.foo(a::get, b::somethingelse);
The only way I can imagine is this:
public int foo(A p) {
return internal_foo(p);
}
public int foo(B p) {
return internal_foo(p);
}
private int internal_foo(Object p) {
if (p instanceof A) {
return ((A)p).get();
}
if (p instanceof B) {
B b = (B)p;
ret = b.somthingelse();
return ret + b.get();
}
throw new ClassCastException("Wrong type");
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With