繁体   English   中英

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

[英]Make a class extends another class at runtime

有一个库具有执行某些任务的基类(我们称其为CBase),并且可以创建扩展此CBase类的类。

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

到现在为止一切正常。 但是让我受阻的是我想用MyCBase代替CBase。 但是,我有很多扩展CBase的类,并且我不想全部更改。

是否可以在运行时用MyCBase替换CBase? 以便

public class A extends CBase {}

public class A extends MyCBase {}

我可以使用代码增强功能执行此操作吗? (就像我们在运行时向类中添加方法一样。是否也可以通过这种方式更改继承?)

谢谢您的帮助 !

编辑

我想为框架编写一个插件,这就是为什么我想在运行时更改继承。 这样,框架的用户可以使用我的插件而无需更改其源代码(将其类的继承从CBase更改为MyCBase)

编辑2

是否可以这样做:

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

我不是专家。 可能您可以扩展ClassLoader 但我强烈建议您不要这样做。 替换将涉及您的许多类,但在代码读取和应用执行中将很明显。

我认为,因为您有太多扩展CBase类,所以体系结构还有改进的空间。 人们正在尝试从其他库中删除依赖项或将其保持很小。 因为在这种情况下,您可以轻松切换到另一个库或添加自己的功能。

我不认为您可以在运行时更改类的扩展。 我建议更改对象的扩展或构建一个接口,其中包含您需要的所有内容

更改所有派生类很简单,只要您控制它们的源代码即可:

  1. 在您的项目中创建一个新类。 将其称为CBase,并将其与库类放在同一包中。
  2. 使用IDE的重命名/移动重构将CBase重命名为MyBase。 这将使IDE重命名对重命名/移动的类的所有引用。
  3. 编写从CBase扩展的MyBase代码。

如果您不能执行此操作(例如,由于某些派生类在您无法控制的库中),则用您自己的CBase实现替换。 只需在项目中创建具有相同包和名称的类(类加载器将按顺序搜索类路径,并使用找到的正确包和名称的第一类)。 但是,这种方法非常脆弱,因为编译器无法检查新旧版本CBase之间的二进制兼容性。 加载类时,JVM将检查此兼容性,但是由于仅在需要时才加载类,因此很难测试您的更改。 (这就是为什么如果有其他选择的话我不推荐这种方法的原因)。

您还可以在操作类文件时更改它们的类,这将变得更加脆弱,并且编译器将允许您使用MyBase可能具有的任何其他功能。 ==>绝对不是一个好主意。

暂无
暂无

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

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