2014-10-30 122 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