2017-01-09 85 views
2

現狀:使用類方法

我想寫像下面這樣的通用功能:

public <T> void do(T para){ 
    para.something(); 
} 

問題: 我想給兩個不同的類的實例do()函數。這兩個班都來自一個設計不好的圖書館。這兩個類都有一個something()方法。但是他們沒有實現相同的接口或擴展相同的超類。

我不過首先:

我可以寫這樣的:

if(para instanceof A){ 
    ((A)para).something(); 
else if(para instanceof B){ 
    ((B)para).something(); 
} 

我想這會的工作,但我需要調用的東西()更頻繁,不想要的垃圾郵件我的代碼用這個if/else。有沒有人有一個很好的線索?提前致謝!

+0

把'something()'方法放到你的類'A'和'B'實現的接口中,並綁定泛型:'public ...'。 –

+1

@AndyTurner這兩個類都來自圖書館 –

+1

正如我所說:A和B從圖書館出來。我不想改變那裏的代碼。 – GAlexMES

回答

2

擴展和接口的方法:

public interface ISomething { 
    public void mySomething(); 
} 

public ExtendA extends A implements ISomething { 
    public void mySomething() { something(); } 
} 

public ExtendB extends B implements ISomething { 
    public void mySomething() { something(); } 
} 

或像在用包裝材料的評論所提到:

public interface ISomething { 
    public void something(); 
} 

public WrapperA implements ISomething { 
    private A a; 

    WrapperA(A a) { 
     this.a = a; 
    } 

    public void something() { 
     return a.something(); 
    } 
} 

public WrapperB implements ISomething { 
    private B b; 

    WrapperB(B b) { 
     this.b = b; 
    } 

    public void something() { 
     return b.something(); 
    } 
} 

A instanceOfA = ...; 
ISomething some = new Wrapper(instanceOfA); 
some.something(); 

另一方法將是反射,這是不一樣快,其它方法我想:

A instanceOfA = ...; 
methodName = "something"; 
Method somethingMethod = instanceOfA.getClass().getMethod(methodName); 
somethingMethod.invoke(instanceOfA); 
+0

擴展是個好主意嗎?或者最好做包裝?我認爲最好增加更多解釋。 – HuStmpHrrr

+1

那就是爲什麼我問他們包含多少種方法。 –

+0

@Kevin Wallis看起來不錯。問題是,我不是自己創建實例。它們是庫中的返回值。 – GAlexMES

3

既然你不能改變現有的圖書館,你可以讓自己的界面:

public interface SomeInterface { 
    void doSomething(); 
} 

public class C extends A implements SomeInterface { 
    @Override 
    public void doSomething() { 
     this.something(); 
    } 
} 

public class D extends B implements SomeInterface { 
    @Override 
    public void doSomething() { 
     this.something(); 
    } 
} 

public <T extends SomeInterface> void do(T param) { 
    param.doSomething(); 
} 

正如在評論中提到它可能是最好不要延長A和B,但要保持的實例變量和的B你的包裝類:

public class C implements SomeInterface { 

     private A a; 
     public C(A a) { this.a = a; } 

     @Override 
     public void doSomething() { 
      a.something(); 
     } 
} 

而且,與Java 8,這可能是一個簡單的解決方案:

@FunctionalInterface 
public interface SomeInterface { 
     void doSomething(); 
} 
public <T extends SomeInterface> void do(T param) { 
    param.doSomething(); 
} 
do(p -> a.something()); 
+0

你更快; –

+0

@Bene 看看好。問題是,我不是自己創建實例。它們是庫中的返回值。 – GAlexMES

+0

爲什麼功能接口更好?我仍然需要創建Wrapper類,並且仍然需要一個通用函數。我看不出優勢。 – GAlexMES