简体   繁体   中英

Java platform-dependent class inheritance

I develop a Java library which shall run on two different platforms. To print messages, one platform uses printA(str) method, while another uses printB(str) method. In C++, I'd create a static method:

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

Since Java has no #ifdef , it becomes a tricky task. I started to look at overriding abstract class with a static method, but not sure I go the right direction. What is the most elegant way to do that?


Edit: With answer of Andy Thomas (thanks!) I found the solution that suits me. The only drawback - it must be initialized on startup. Below is the code. Common library:

//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);
    }
}

Calling of this function is the same in common library and platform-specific code:

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

Code for each platform has to have the platform specific implementation of the interface, eg platformA (for B it is identical):

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

Usage:

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!");
        }
}

Use a constant expression:

private static final boolean PLATFORM_A = true;

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

What about this code?

    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;
        }
    }
}

You could use the strategy pattern .

Define the interface once, and implement it in OS-specific classes.

    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
       }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM