2

いくつかのタスクを実行する基本クラス (CBase と呼びましょう) を持つライブラリがあり、この CBase クラスを拡張するクラスを作成できます。

CBase の動作は私にとって十分ではないので、同じメソッドとメンバーを持つ独自の CBase クラス (MyCBase と呼びましょう) を作成したいと思いますが、これらのメソッドは同じことを行いません。

今まではすべて問題ありません。しかし、私を妨げているのは、CBase を MyCBase に置き換えたいということです。ただし、CBase を拡張する多くのクラスがあり、それらすべてを変更したくありません。

実行時に CBase を MyCBase に置き換えることは可能ですか? となることによって

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。しかし、私はそれをしないことを強くお勧めします。置き換えは多くのクラスに影響しますが、コードの読み取りとアプリの実行では明確になります。

非常に多くのクラスが extends しているため、アーキテクチャにも改善の余地があると思いますCBase。人々は、他のライブラリから依存関係を削除したり、ライブラリを非常に小さくしたりしようとしています。この場合、別のライブラリに簡単に切り替えたり、独自の機能を追加したりできるためです。

于 2012-07-25T09:00:59.020 に答える
0

すべての派生クラスを変更するのは、ソース コードを管理していれば簡単です。

  1. プロジェクトに新しいクラスを作成します。これを CBase と呼び、ライブラリ クラスと同じパッケージに入れます。
  2. IDE の名前変更/移動リファクタリングを使用して、CBase を MyBase に名前変更します。これにより、IDE は名前変更/移動されたクラスへのすべての参照の名前を変更します ...
  3. CBase から拡張して、MyBase のコードを記述します。

これができない場合 (たとえば、一部の派生クラスが制御できないライブラリにある場合など)、CBase の実装を独自のものに置き換えます。プロジェクトで同じパッケージと名前のクラスを作成するだけです (クラスローダーはクラスパスを順番に検索し、見つかった適切なパッケージと名前の最初のクラスを使用します)。ただし、このアプローチは、コンパイラが CBase の古いバージョンと新しいバージョンの間のバイナリ互換性をチェックできないため、非常に脆弱です。JVM は、クラスがロードされるときにこの互換性をチェックしますが、クラスは必要なときにのみロードされるため、変更をテストするのは困難です。(他のオプションがある場合、このアプローチをお勧めしないのはそのためです)。

また、クラス ファイルを操作して読み込まれるときにクラスを変更することもできますが、これはさらに脆弱になり、コンパイラにより、MyBase が持つ可能性のある追加機能を使用できるようになります。==>間違いなく良い考えではありません。

于 2012-07-25T09:12:55.707 に答える
0

実行時にクラスの拡張を変更できるとは思わない。オブジェクトの拡張を変更するか、必要なものをすべて含むインターフェイスを構築することをお勧めします

于 2012-07-25T09:06:52.933 に答える