Reputation: 823
There is a library have a base class (let's call it CBase) that performs some tasks and one can create classes that extends this CBase class.
The behavior of the CBase is not enough for me, so I would like to create my own CBase class (let's call it MyCBase) that have the same methods and members but these methods don't do the same thing.
Until now everything is ok. But what blocks me is that I would like to replace CBase by MyCBase. However, I have a lot of classes that extend CBase and I don't want to change them all.
Is it possible to replace CBase by MyCBase at runtime ? So that
public class A extends CBase {}
becomes
public class A extends MyCBase {}
Can I perform this using code enhancement ? (like we do to add methods to a class at runtime. Is it also possible to change inheritance this way ?)
Thank you for your help !
EDIT
I would like to write a plugin for a framework, this is why I would like to change inheritance at runtime. This way users of the framework can use my plugin without changing their source code (changing the inheritance of their classes from CBase to MyCBase)
EDIT 2
Is it possible to do like this: ?
CtClass cc = CtClass.forName("pkg.AClass");
cc.setSuperclass(CtClass.forName("mylib.MyCBase"));
cc.compile();
Upvotes: 2
Views: 1991
Reputation: 70584
Changing all derived classes is a simple matter, provided you control their source code:
If you can not do this (for instance because some derived classes are in a library you do not control), you replace the implementation of CBase with your own. Simply create a class of the same package and name in your project (the classloader searches the classpath in order, and uses the first class of the proper package and name it finds). This approach however is very brittle, as the compiler can not check binary compability between the old and new version of CBase. The JVM will check this compatibility when classes are loaded, but since classes are only loaded when needed, its hard to test your changes. (Which is why I do not recommend this approach if there are other options).
You could also change the classes as they are loaded my manipulating the class file, that that's going to be even more brittle, and the compiler would allow you to use any additional features MyBase might have. ==> Definitely not a good idea.
Upvotes: 0
Reputation: 420
I dont think you can change the extends of a class at runtime. I would suggest to change the extends of the objects or build an interface, which contains all the things your need
Upvotes: 0
Reputation: 20140
I'm not expert. Probably you could extend ClassLoader
. But I highly recommend don't do it. The replacement will touch many of your classes but it will be clear in code reading and app execution.
I think there is also room for architecture improvement since you have so many classes extend CBase
. People are trying to remove dependencies from other libraries or keep it really small. Because in this case you could easily switch to another library or add your own functionality.
Upvotes: 1