Java - override external method
I am trying to make spcial additions for my application. I need to override some class methods without editing the class file.
Here's a diagram:
class A
{
public void method1()
{
// Do something here
}
public int method2()
{
// Do something
}
}
Now from my class B, I want to override the method1 function from class A and force class A to use my new method.
class B
{
public void method1()
{
Do something
}
}
I want to update the code of class A without editing class A. Is this possible?
Thank.
source to share
It looks like a proxy might solve your problem. Take a look at cglib
Enhancer e = new Enhancer();
e.setSuperclass(A.class);
e.setCallback(new MyCallback());
A proxied = e.create();
And here is a sample instance of the MyCallback class ...
class MyCallback implements MethodInterceptor{
public Object intercept(Object obj,
Method method,
Object[] args,
MethodProxy proxy){
Object stuffToReturn = null;
if ("method1".equals(method.getName()) {
//Class B method1 impl
} else {
//call the original method in class A
stuffToReturn = method.invoke(proxy, args);
}
return stuffToReturn;
}
}
source to share
No, in languages like Java this is not possible directly. new A
always creates an instance at runtime A
, not a derivative B
.
If possible (i.e. if you control all the code that instantiates A
), you can use some awkward workarounds that introduce a kind of indirection. For example, you can set up a factory A
(which will switch to create B
under the cover on demand ) - this is similar to the Java way. (You will need the whole code construct A
not directly, but via a factory.)
If I'm not mistaken, the function you're looking for is available in Objective C out of the box, but not in Java.
source to share
This makes no sense. Overriding means exactly overriding a method that is inherited from the superclass. So, here are some solutions:
- B must extend A, and then you can override one of A.'s methods. Give it the same signature as in A, use @Override annotation.
- A has some dependency which is injected: method1 and method2 use some tierce object (C) to do the job, and the dependency is injected into A. Then B can use A with a custom C object that suits his needs. Most of A's code won't change this way.
source to share
One way to achieve this would be to use a kind of instance factory to create objects of type A instead of calling A () directly in your code. Your add-in will then need to provide and register its own implementation of this factory, which will create instances of class B. This only works if the add-in is loaded and initialized before any instances of A are created.
Another approach would be to implement your own ClassLoader and use that to modify the bytecode of class A at load time. You can look for aspect-oriented programming tools to implement this. This is only possible if you control the loading process of class A.
source to share
No, you cannot do that, it is not possible to change the behavior of the class without actually changing the class, however there is a workaround:
-
B should be inherited from A. This is absolutely necessary. A will not change, but his classes of children may change in behavior
-
Overwrite method1 () and method2 ()
-
Suppose you have an object of class A. If you convert it to B, its behavior will be your new, custom behavior.
source to share