2011-11-24 69 views
5

是否可以反思重寫某個給定類的實例的方法?重寫一個類的實例的方法?

先決條件:遊戲有一個可覆蓋的方法act()

public class Foo { 

    public Method[] getMethods() { 
    Class s = Game.class; 
    return s.getMethods(); 
    } 

    public void override() 
    { 
    Method[] arr = getMethods() 
    for (int i = 0; i<arr.length; i++) 
    { 
     if (arr[i].toGenericString().contains("act()") 
     { 
     // code to override method (it can just disable to method for all i care) 
     } 
    } 
    }     
} 
+1

可以使用字節碼工程和代理來做類似的事情,除非你真的需要這種黑魔法,只是使用組合和委派。 –

+2

爲什麼僅使用局部匿名內部類的方法是不夠的?繼承實際的類。 – zeller

+0

從給定的實例動態創建子類,重寫該類中的act方法並處理先前的實例會更容易嗎? –

回答

7

如果遊戲是一個接口或實現與方法的接口act()您可以使用Proxy了點。如果界面很小,最優雅的方式可能是創建一個實現它的類,使用Decorator design pattern

+2

+1的裝飾建議。這裏不需要反思。 – artbristol

+2

遊戲是一個類 –

+0

代碼示例? –

1

使用純Java動態重寫類的方法是不可能的。 The third-party library cglib可以創建動態子類。你可能想檢查一下。

如果您可以針對接口進行編碼,那麼您可以使用Java dynamic proxy創建一個覆蓋行爲的代理對象,如下例所示。假設Game正在實現接口IGame

class GameInvocationHandler implements InvocationHandler 
{ 
    private Game game; 
    public GameInvocationHandler(Game game) 
    { 
     this.game = game; 
    } 
    Object invoke(Object proxy, Method method, Object[] args) 
    { 
     if (method.toGenericString().contains("act()") 
     { 
      //do nothing; 
      return null; 
     } 
     else 
     { 
      return method.invoke(game, args); 
     } 
    } 
} 

Class proxyClass = Proxy.getProxyClass(Foo.class.getClassLoader(), IGame.class); 
IGame f = (IGame) proxyClass.getConstructor(InvocationHandler.class).newInstance(new Object[] { }); 
相關問題