2017-05-02 46 views
0

而在Java編程編碼,我有如下的問題。如何在java類中有效地生成函數指針?

下面是C++代碼。如你所知,可變AlphaSomParam class是函數指針。當用戶在構造設置的功能地址到Alpha,則變量Alpha執行當前的功能。

double lin_alpha(double alpha_0, int t, Subscript rlen, double) { 
    return alpha_0 * (1.0 - (double) t/rlen); 
} 

double inv_alpha(double alpha_0, int t, Subscript rlen, double C) { 
    //double C = rlen/INV_ALPHA_CONST; 

    return alpha_0 * C/(C + t); 
} 

#define LIN_ALPHA 1 
#define INV_ALPHA 2 

class SomParam{ 
public: 
    typedef double Alpha(double, int, int, double); 
protected: 
    Alpha *_alpha; 
    int _xdim; 
    int _ydim; 

public: 
    SomParam(int AlphaType,int xdim, int ydim) { 
     if (AlphaType == LIN_ALPHA) _alpha = lin_alpha; 
     else _alpha = lin_alpha; 
    _xdim = xdim; 
    _ydim = ydim; 
    } 

我的問題是,我想知道如何將上面的代碼轉換爲Java版本。由於Java沒有指針概念,所以我很難將其轉換爲Java版本。我已經知道接口可能能夠替換Java中的函數指針,但我無法將其應用於我的代碼。 如何將上面的一個轉換爲java版本?

Ps。我希望,因爲我使用的是Java,你不應該使用lambda表達式7

+0

我不認爲在java中有函數指針。然而,java8 lambda參數看起來像一個函數作爲參數傳遞。 – Tiina

+0

爲什麼不使用Java 8?Java 7已經相當一段時間過時了。 –

回答

1

做到這一點,最好的辦法是與Java 8 Lambda表達式。但是因爲你想避免這些,所以這裏粗略地把你的C++代碼翻譯成Java 7.我使用了一個靜態的內部接口來表示函數指針的類型,並且這個接口的匿名實現的實例代表功能本身。在我看來,這比使用enum好,因爲它並不意味着各種功能之間的任何關係,除了它們具有相同的簽名之外。

我已經用常量設置了這一切,並展示瞭如何選擇哪些常量值適合存儲在您正在實例化的對象中。我已經採取了一些自由的數據類型等。

public class AlphaAdjuster { 

    private static interface AlphaCalculator { 
     double calculate(double alpha0, int t, int rlen, double c); 
    } 

    public static final int LIN_ALPHA = 1; 
    public static final int INV_ALPHA = 2; 
    private static final AlphaCalculator LIN_ALPHA_CALCULATOR = new AlphaCalculator(){ 
     @Override 
     public double calculate(double alpha0, int t, int rlen, double c) { 
      return alpha0 * (1.0 - (double) t/rlen); 
     }}; 
    private static final AlphaCalculator INV_ALPHA_CALCULATOR = new AlphaCalculator(){ 
     @Override 
     public double calculate(double alpha0, int t, int rlen, double c) { 
      return alpha0 * c/(c + t); 
     }}; 

    private AlphaCalculator calculator; 
    private int xDim; 
    private int yDim; 

    public AlphaAdjuster(int alphaType, int xDim, int yDim) { 
     if (alphaType == LIN_ALPHA) { 
      calculator = LIN_ALPHA_CALCULATOR; 
     } else { 
      calculator = INV_ALPHA_CALCULATOR; 
     } 
     this.xDim = xDim; 
     this.yDim = yDim; 
    } 

    public double calculate(double alpha0, int t, int rlen, double c) { 
     return calculator.calculate(alpha0, t, rlen, c); 
    } 
} 
3

我建議建立一個戰略格局枚舉實現兩個功能和傳球直接到你的構造:

public enum AlphaType { 
    LIN_ALPHA { 
     @Override 
     public double compute(double alpha_0, int t, Subscript rlen, double C) { 
      // FIXME t/rlen isn't valid in Java 
      return alpha_0 * (1.0 - (double) t/rlen); 
     } 
    }, 

    INV_ALPHA { 
     @Override 
     public double compute(double alpha_0, int t, Subscript rlen, double C) { 
      //double C = rlen/INV_ALPHA_CONST; 
      return alpha_0 * C/(C + t); 
     } 
    }; 

    public abstract double compute(double alpha_0, int t, Subscript rlen, double C); 
} 
-1

我對C++不太熟悉,但我想我明白你想要什麼。

你是正確的,界面似乎是你想要的。你可以閱讀關於接口here,但他們會完成你想要的。

例如,假設你有接口:

public interface MyInterface { 
    public int sort(int a, int b); 
} 

這使得MyInterface用戶定義自己sort()方法,這取決於他們想要的東西。

MyInterface foo = new MyInterface(){ 
    @Override 
    public int sort(int a, int b){ 
     return (a >= b)? a : b; 
    } 
} 

此實例化一個MyInterface由最大數量給出了排序。撥打foo.sort(1,4)將返回4

在你的情況下,你將有一個接口,看起來像public double alpha(double a, int b, int b, double c)或類似的方法。然後,用戶將實例化您的界面並覆蓋alpha()方法以執行他們想要的操作。

+0

我從未想過將接口當作函數指針。我的建議是堅持一個可靠的答案,不要依賴C++和Java之間的相關性。 – Makoto

+0

@Makoto同意,我不認爲應該做這種類型的連接,但我只是試圖用C++術語解釋接口,所以他可以理解它。我將進行編輯以明確界面與函數指針不同,但在這種情況下可以用來完成他想要的功能。 – coolioasjulio

+0

這個答案有很好的解決方案。不幸的是,最後一句中的術語很奇怪。我們沒有實例化一個接口,然後重寫它的方法。我們實例化一個匿名的接口實現。 –