簡體   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