简体   繁体   English

使一个类在运行时扩展另一个类

[英]Make a class extends another class at runtime

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. 有一个库具有执行某些任务的基类(我们称其为CBase),并且可以创建扩展此CBase类的类。

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. CBase的行为对我来说还不够,因此我想创建自己的CBase类(我们称其为MyCBase),这些类具有相同的方法和成员,但这些方法不能做相同的事情。

Until now everything is ok. 到现在为止一切正常。 But what blocks me is that I would like to replace CBase by MyCBase. 但是让我受阻的是我想用MyCBase代替CBase。 However, I have a lot of classes that extend CBase and I don't want to change them all. 但是,我有很多扩展CBase的类,并且我不想全部更改。

Is it possible to replace CBase by MyCBase at runtime ? 是否可以在运行时用MyCBase替换CBase? 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) 这样,框架的用户可以使用我的插件而无需更改其源代码(将其类的继承从CBase更改为MyCBase)

EDIT 2 编辑2

Is it possible to do like this: ? 是否可以这样做:

CtClass cc = CtClass.forName("pkg.AClass");
cc.setSuperclass(CtClass.forName("mylib.MyCBase"));
cc.compile();

I'm not expert. 我不是专家。 Probably you could extend ClassLoader . 可能您可以扩展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 . 我认为,因为您有太多扩展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. 因为在这种情况下,您可以轻松切换到另一个库或添加自己的功能。

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 我建议更改对象的扩展或构建一个接口,其中包含您需要的所有内容

Changing all derived classes is a simple matter, provided you control their source code: 更改所有派生类很简单,只要您控制它们的源代码即可:

  1. Create a new class in your project. 在您的项目中创建一个新类。 Call it CBase, and put it in the same package as the library class. 将其称为CBase,并将其与库类放在同一包中。
  2. Use the rename/move refactoring of your IDE to rename CBase to MyBase. 使用IDE的重命名/移动重构将CBase重命名为MyBase。 This will have the IDE rename all references to the renamed/moved class ... 这将使IDE重命名对重命名/移动的类的所有引用。
  3. Write the code for MyBase, extending from CBase. 编写从CBase扩展的MyBase代码。

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. 如果您不能执行此操作(例如,由于某些派生类在您无法控制的库中),则用您自己的CBase实现替换。 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. 但是,这种方法非常脆弱,因为编译器无法检查新旧版本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. 加载类时,JVM将检查此兼容性,但是由于仅在需要时才加载类,因此很难测试您的更改。 (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. 您还可以在操作类文件时更改它们的类,这将变得更加脆弱,并且编译器将允许您使用MyBase可能具有的任何其他功能。 ==> Definitely not a good idea. ==>绝对不是一个好主意。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM