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

时间:2012-07-25 08:54:17

标签: java class inheritance runtime extends

有一个库有一个基类(让我们称之为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();

3 个答案:

答案 0 :(得分:1)

我不是专家。可能你可以扩展ClassLoader。但我强烈建议不要这样做。替换将触及您的许多课程,但在代码阅读和应用程序执行中将会很清楚。

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

答案 1 :(得分:0)

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

答案 2 :(得分:0)

如果您控制源代码,则更改所有派生类很简单:

  1. 在项目中创建一个新类。将其称为CBase,并将其放在与库类相同的包中。
  2. 使用IDE的重命名/移动重构将CBase重命名为MyBase。这将使IDE重命名对重命名/移动的类的所有引用...
  3. 编写MyBase的代码,从CBase扩展。
  4. 如果你不能这样做(例如因为某些派生类在你无法控制的库中),你可以用自己的实现替换CBase的实现。只需在项目中创建一个相同包和名称的类(类加载器按顺序搜索类路径,并使用正确的包的第一个类和它找到的名称)。然而,这种方法非常脆弱,因为编译器无法检查旧版本和新版本的CBase之间的二进制兼容性。加载类时,JVM将检查此兼容性,但由于类仅在需要时加载,因此很难测试您的更改。 (这就是为什么我不推荐这种方法,如果有其他选择)。

    您也可以在加载类时更改类操作类文件,这样会更加脆弱,编译器会允许您使用MyBase可能具有的任何其他功能。 ==>绝对不是个好主意。