Simulate multiple inheritance in Java

A trick for extending multiple classes

Java's single inheritance limitation is usually not a problem in the normal course of development. In fact, the need to use multiple inheritance could be a sign of a bad design. There are times, however, when developers wish they could extend more than one class. Although Java prevents a developer from extending more than one class, a simple trick can be used to simulate multiple inheritance.

I have used this technique in both a Swing application and a Web-based application. The Swing application packaged and deployed services to application servers. In that case, I needed multiple inheritance because I was adding the ability to drag and drop objects between the different components of the GUI and wanted all the GUI components to share the same drag-and-drop methods. Thus, all the GUI components needed to extend two classes: the GUI component itself (a JTree or JList) and the common drag-and-drop class. The technique described in this article simplified the drag-and-drop implementation.

To illustrate my technique for simulating multiple inheritance in Java, let's examine how to use it in a Web-based application, where the Servlet class, along with another class, needs to be extended. The application being developed is a text-based message system used to send text messages to a mobile phone from another mobile phone, the Web, a PDA, or some other device with access to the Web or the phone network.

The heart of the system is a message server that receives a message from a client and forwards it to the appropriate phone. To make client development easier, I developed a MessageClient class to contain all the common methods needed to communicate with the message server. The class facilitates client development because it can be used as the base class for all the possible clients.

The MessageClient class, shown in Listing 1, contains three methods. The sendMessage() method sends the actual message to the server. connectToServer() connects to the message server, which, in this example, is an RMI (remote method invocation) server. The last method is getServerName(), which is an abstract method because each device that uses this class has a different way of determining the name of the message server. This means that all the clients that extend MessageClient must implement the getServerName() method.

Listing 1. MessageClient

 import java.rmi.Naming;

public abstract class MessageClient
{
   private MessageServer messageServer;

   public MessageClient()
   {
      System.out.println("Initializing Message Client");
   }
   /**
    * Method used to connect to the message server
    *
    * @param serverName name of the server that contains the message server
    */
   protected void connectToServer()
   {
      String serverName = getServerName();
      try
      {
         String name = "//" + serverName + "/MessageServer";
         messageServer = ((MessageServer) Naming.lookup(name));
      }
      catch(Exception e)
      {
         System.out.println("Error connecting to Message Server.  Exception is " + e);
         e.printStackTrace();
      }
   }

   /**
    * Method used to send message to server
    *
    * @param phoneNum phone number to send message to
    * @param message message to send
    */
   public boolean sendMessage(String phoneNum, String message)
   {
      try
      {
         return(messageServer.sendMessage(phoneNum,message));
      }
      catch(Exception e)
      {
         System.out.println("Error Sending Message.  Exception is " + e);
         e.printStackTrace();
         return(false);
      }
   }

   public abstract String getServerName();
}

We need multiple inheritance when developing the Web client that talks to the message server. Our Web client is a simple servlet used to get the message from a form and send it to the message server. To complete that task, the servlet must be both an

HttpServlet

and a

MessageClient

. Since Java does not allow such behavior, the main class extends the

HttpServlet

class, as shown in Listing 2. This main class contains an inner class that extends

MessageClient

. The outer class then creates an instance of the inner class.

Listing 2. SendMessageServlet

 public class SendMessageServlet extends HttpServlet{

   private MessageClient m_messageClient;
   private String m_serverName;

   public void doGet(HttpServletRequest request, HttpServletResponse response)
         throws ServletException, IOException{
      try{
        //Get server name
         m_serverName = request.getServerName();
         System.out.println("ServerName is " + m_serverName);
         //Create message client to communicate with message server
         m_messageClient = new ServletMessageClient();
         System.out.println("Created Message Client");
         m_messageClient.connectToServer();

         //Get message and phone number
         String phoneNum = (String) request.getParameter("PhoneNum");
         String message = (String) request.getParameter("Message");

         //Send message
         m_messageClient.sendMessage(phoneNum,message);

         //Display page to tell user message was sent
         response.setContentType("text/html");
         RequestDispatcher dispatcher = getServletContext().getRequestDispatcher("/SendMessageForm.jsp");
         dispatcher.include(request, response);
      }catch (Exception e){
         e.printStackTrace();
      }
   } 

   public void doPost(HttpServletRequest request, HttpServletResponse response)
         throws ServletException, IOException   {
      doGet(request, response);
   }

    /** Inner class used to extend MessageClient     */
    public class ServletMessageClient extends MessageClient {
       public ServletMessageClient(){
         super();
       }
       public String getServerName(){
          System.out.println("Returning ServerName " + m_serverName);
          return(m_serverName);
       }
    }
}

This approach isn't true multiple inheritance because we used delegation. (i.e.,

MessageClient

is extended by a member of the outer class and not the outer class itself), but the effect is the same. Although

MessageClient

could have been extended in a separate class, using an inner class allows it to access all the members and methods of the outer class. This makes it easier for the two classes to interact.

This example only extends two classes, but there is no reason why this technique couldn't be used to extend as many classes as needed by creating an inner class for each class that must be inherited.

Note that the message server example could have been completed without multiple inheritance. If the

MessageClient

class had a constructor that accepted the server name, the

getServerName()

method would not need to be abstract, which means the Web client would not have to extend the

MessageClient

class. The Web client could have used the class directly. Developers should be cautious and only use multiple inheritance if a clear reason warrants it because multiple inheritance complicates design and is easily misused.

Tom Hammell is a senior developer and currently works on the development of telecom network infrastructure software for the OpenCall Business Unit of Hewlett-Packard. Hammell has been developing software for more than 18 years and has worked on software in many different fields such as satellite navigation, financial news wires, telecom, and J2EE application server development. Hammell has published a number of articles on Java topics ranging from Swing development to unit testing and recently wrote a book on test-driven development. Hammell holds a bachelor's of science in electrical engineering and a master's of computer science from Steven's Institute of Technology.

Learn more about this topic

Recommended
Join the discussion
Be the first to comment on this article. Our Commenting Policies
See more