Reputation: 6649
A service from external API which I am not allowed to modify returns me
MyClass instance = ServiceUtil.getThing();
I would like to extend this returned class and Add/Override a method but leave intacts the others, say 150 methods.
private class MyWrapperClass extends MyClass(){
public MyWrapperClass(){super();}
@Override public String toString(){ return "Blocked toString"; }
}
Is there any way to force this "casting" from the returned MyClass instance to my newly particular subtype??
NOTE: Please, not suggest the approach of making a constructor, passing the original object and having to copy and implement the 150 methods to call the wrapped object
Upvotes: 0
Views: 689
Reputation: 13841
If MyClass is an interface look at java.lang.reflect.Proxy and java.lang.reflect.InvocationHandler.
You can implement a dynamic proxy that always does the same. It is, always pass control to your original implementation... except when method X is invoked.
Something like:
class MyHandler implements InvocationHandler {
Object invoke(Object proxy, Method method, Object[] args) {
if (method is the one you want to change) {
do whatever
else
return method.invoke(originalObject, args);
}
}
Note: you must create this proxy implementation anyway:
MyClass original = ServiceUtil.getThing();
MyClass proxy = (MyClass) Proxy.newProxyInstance(
MyClass.class.getClassLoader(), // classloader to use
new Class[] { MyClass.class }, // interfaces to implement
new MyHandler()); // who does the dirty work when methods are invoked
Upvotes: 7
Reputation: 114817
I hope I get you right: you have a
MyClass instance = ServiceUtil.getThing();
but want something like
MyWrapperClass instance = (MyWrapperClass) ServiceUtil.getThing();
(which obviously doesn't work, even though MyWrapperClass
extends MyClass
).
The solution is to create a new instance of MyWrapperClass
based on the MyClass
and, sorry to say that, using the constructor is a good approach (public MyWrapperClass(MyClass myClass)
).
Upvotes: 5
Reputation: 24134
Please, not suggest the approach of making a constructor, passing the original object and having to copy and implement the 150 methods to call the wrapped object
You mean to say that "decoration" is not an option you would like to look at right?
But decoration will be a problem to you if MyClass is an interface type where you have to define those 150 odd methods, delegating the 149 method calls onto the decorated and overriding that one method.
If MyClass is a class type, then you don't need to write those 149 methods, right? or Did I get you completely wrong?
Upvotes: 1