2

有一个库有一个执行某些任务的基类(我们称之为 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();
4

3 回答 3

1

我不是专家。也许你可以延长ClassLoader. 但我强烈建议不要这样做。替换将触及您的许多类,但在代码阅读和应用程序执行方面会很清楚。

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

于 2012-07-25T09:00:59.020 回答
0

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

于 2012-07-25T09:06:52.933 回答
0

更改所有派生类是一件简单的事情,只要您控制它们的源代码:

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

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

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

于 2012-07-25T09:12:55.707 回答