2011-08-29 60 views
1

例如,假設我有以下基類我不能修改源代碼在Scala中,除繼承外,還有一種技術可以知道什麼時候調用了基類方法?

class Base { 
    def someMethod = ... 
} 

如果我定義了一個子類

class Sub extends Base { 
    override def someMethod = ... 
} 

當我做

VAL子=新Sub

然後我自動「知道」什麼時候調用someMethod,因爲sub.someMethod被觸發。不過,我想避免的子類,所以我在想,如果有一些技術,藉此我可以做

class NotSubclass { 
    val Base = new Base 
} 

或類似

而且有點「重視」,從基地的someMethod使NotSubclass會「知道」時的someMethod被稱爲。澄清一些方法被稱爲外部我從來沒有在我自己的代碼中打電話。

回答

5

如果您正在修改您沒有源代碼的類的行爲,那麼您可以嘗試查看Aspect-Oriented programming

Aspects允許您'包裝'一個方法調用,以便您可以記錄信息,修改輸入參數或返回值,甚至可以完全替換方法調用。

如果你想要做的只是記錄信息,那麼這將是一個好方法。然而,方面可能會導致代碼很難理解,如果您在任何地方都使用它們,請確保它符合您的使用案例。

您需要定義你感興趣的方法pointcut

Scala-IDE使用方面編織代碼到JDT,它採用AspectJ,所以它不使用Scala工作。

+0

@deltanovember:所以你不能改變源代碼,但不知怎的後處理編譯的類文件是好的? –

1

您的意思是這樣的?

class NotSubclass { 
    val base = new Base 

    def someMethod = base someMethod 
} 
+1

不完全是因爲如果base.someMethod是從外部調用的,我想要NotSubclass。someMethod自動被稱爲 – deltanovember

+0

哦,你的意思是,任何時候任何人*無論*他們調用'BaseSomeMethod',無論他們是否有你的'NotSubclass'? – Owen

+0

有關具體示例,假設Base在實例化時自動開始獲取股票市場數據。每當價格更新(通過someMethod)NotSubclass – deltanovember

2

如果該方法屬於一個接口,您可以重新實現幷包裝Base。否則你運氣不好。

0

我想你可以使用字節碼操作。 PowerMock允許模擬構造函數,所以我猜測可以使用相同的技術來替換Base的字節代碼,以完成您需要完成的任何事情。

當然,這種方法將:

  • 是任何人是沒有意識到這一點極其混亂。
  • 如果您沒有受控制的類加載器,則會失敗。
  • 可能會違反法律約束條件
  • 對於生產代碼來說只是一個壞主意。
相關問題