2014-10-30 86 views
0

我開發了一個Java庫,它將在兩個不同的平臺上運行。要打印消息,一個平臺使用printA(str)方法,而另一個使用printB(str)方法。在C++中,我想創建一個靜態方法:Java依賴於平臺的類繼承

public static void print(string str) 
{ 
    #ifdef platformA 
     printA(str); 
    #else 
     printB(str); 
    #endif 
} 

由於Java沒有#ifdef,就成了一個棘手的任務。我開始考慮用靜態方法重寫抽象類,但不確定我是否朝着正確的方向前進。什麼是最優雅的方式來做到這一點?


編輯:(!感謝)和安迪·托馬斯的答案,我發現適合我的解決方案。唯一的缺點 - 它必須在啓動時初始化。以下是代碼。 公共庫:

//interface is only for internal use in Output class 
public interface IPrintApi 
{ 
    public void Print(String message); 
} 

public abstract class Output 
{ 
    private static IPrintApi m_api; 
    public static void SetPrintAPI(IPrintApi api) 
    { 
     m_api=api; 
    } 

    public static void MyPrint(String message) 
    { 
     m_api.Print(message); 
    } 
} 

此功能的呼叫是在公共庫和特定於平臺的代碼相同:

public class CommonTest 
{ 
    public CommonTest() 
    { 
     Output.MyPrint("print from library"); 
    } 
} 

代碼爲每個平臺都必須有特定於平臺實現的接口,例如中platformA(對於B是相同的):

public class OutputA implements IPrintApi 
{ 
    public void Print(String message) 
    { 
     //here is our platform-specific call 
     PrintA(message); 
    } 
} 

用法:

public class AppPlatformA 
{ 
     public static void main(String[] args) 
     { 
      // point the abstract Output.Print function to the available implementation 
      OutputA myPrintImpl = new OutputA(); 
      Output.SetPrintAPI(myPrintImpl); 
      // and now you can use it! 
      Output.MyPrint("hello world!"); 
     } 
} 
+0

[http://stackoverflow.com/questions/228477/how-do-i-programmatically-determine-operating-system-in-java][1] 我認爲這可以幫助你。 – nikoliazekter 2014-10-30 16:16:35

+0

這不是一個運行時檢測的問題,它更多的是避免編譯時問題的代碼設計:printA在我使用platformB庫時沒有定義,反之亦然... – 2014-10-30 17:19:46

回答

0

你可以使用strategy pattern

定義一次接口,並在OS特定的類中實現它。

public interface IPlatformAPI { 
     public void print(String str); 
    } 

    public class WindowsPlatformAPI implements IPlatformAPI { 
     public void print(String str) { ... } 
    } 

    public class MacPlatformAPI implements IPlatformAPI { 
     public void print(String str) { ... } 
    } 

    public class LinuxPlatformAPI implements IPlatformAPI { 
     public void print(String str) { ... } 
    } 

    public class PlatformAPI { 
     public static IPlatformAPI getPlatformAPI() { 
      // return one of the platform APIs 
      // You can use System.getProperty("os.name") to choose the implementation 
     } 
    } 
+1

謝謝。聽起來很有趣。唯一不清楚的一點是如何在PlatformAPI類中引用三個不兼容的類,這些類由於不同的與植物形式有關的包含而不能編譯在一起。在這種情況下,打印方法不能被視爲靜態... – 2014-10-30 17:14:57

+0

首先,驗證您不能編譯所有針對特定平臺的Java代碼。如果你不能,那麼一種選擇是在運行時用'Class.forName()'和'Class.newInstance()'加載適當的類。順便說一句,歡迎來到StackOverflow。通過點擊左邊的複選標記,您可以*接受*您認爲最好的答案。你可以*注意*你認爲有用的多個答案。 – 2014-10-30 18:32:11

+0

我接受這個答案。我不得不修改你的例子,但現在它按我的意願工作,對我來說看起來不錯。我稍後會發布示例代碼。 – 2014-10-31 09:45:08

1

使用常量表達式:

private static final boolean PLATFORM_A = true; 

public static void print(string str) 
    { 
    if(PLATFORM_A) 
    { 
     printA(str); 
    } 
    else 
    { 
     printB(str); 
    } 
    } 
+0

不斷的使用並不是很好。我在兩個平臺上同時使用它,即Windows和Android。而且我不想每次都在通用代碼中更改const ... – 2014-10-30 16:53:39

+0

然後您可以使用System.getEnv()並根據環境執行。 – 2014-10-30 16:58:26

1

這個怎麼樣的代碼?

public class Example { 

    public static void main(String[] args) { 
     print(); 
    } 

    public static void print() { 
     String platform = System.getProperty("os.name"); 
     switch (platform) { 
     case "Windows 7": 
      System.out.println("This is Windows 7"); 
      break; 
     case "Windows XP": 
      System.out.println("This is Windows XP"); 
      break; 
     } 
    } 
} 
+0

謝謝,但問題更多的是關於不同的API調用,而不是如何檢測平臺。 – 2014-10-30 17:00:50