Section 16.7 - Java Interfaces and Aliased Components

Java also includes a construct called an "interface". Java interfaces are basically a weakened form of multiple inheritance. A Java interface is like a class you can inherit from, but all of its methods must be abstract. A class that "inherits" from an interface is said to "implement" that interface. Java classes can implement (inherit) from zero, one, or more than one interface. Thus, while Java classes can only directly inherit from one other class (as is true with Ada), they can implement zero or more interfaces.

Ada doesn't have anything that directly corresponds to a Java interface. However, to use the Java library there must be a way for an Ada program to use Java interfaces. Here's the convention you need: if you're defining an Ada type that is to implement some interface defined in the Java language as I, add to the Ada type's record a field with name "I" and type "aliased I_Obj". For example, let's say you're defining some applet My_Applet and you want it to implement a Java interface named Runnable in Java package "java.lang". You'd define your class as follows:

  with java.applet.Applet; use java.applet.Applet;
  with java.lang.Runnable; use java.lang.Runnable;

  package My_Applet is
    type My_Applet_Obj is new Applet_Obj with
      record
        Runnable : aliased Runnable_Obj;
      end record;
    type My_Applet_Ptr is access all My_Applet_Obj'Class;
  end My_Applet;

All interfaces are marked with a special pragma that tells the compiler that it's an interface and to take special actions to produce the right code.

Some operations will require you to pass the interface type instead of the regular type. For example, some Java library methods require the Java "Runnable" type (instead of, say, Java's "Applet" type). That's not a problem; instead of passing the access value A, pass such methods the value A.Runnable'Access where "Runnable" is the field representing the interface. For example, let's say you want to call the Java "Thread" constructor (called "new_Thread" in Ada). This constructor expects to be handed something of type "Runnable". You can create a new Thread by executing the following:

  My_Thread : Thread_Ptr := new_Thread(X.Runnable'Access);

You can create your own interfaces by identifying their "_Obj" type using pragma Convention with language type "Java_Interface". For example, if Concept_Obj is actually a new interface you're defining, simply say:

  pragma Convention(Java_Interface, Concept_Obj);

The "aliased" phrase above is not specific to Java, but is a standard part of Ada 95. Normally you can only obtain an access value on entire record, not of some component inside. However, sometimes you'd like to have access values that can refer to subcomponents of a record. Ada will let you do that if you identify the component as aliased. For example, the phrase "X.Runnable'Access" used above only works because Runnable is marked as "aliased".

This approach to implementing Java interfaces suggests a simple way to implement multiple inheritance in Ada, should you need to. You can use inheritance to inherit from the "most natural" class. You can then include, in your type's record, components that contain the "other" classes that you'd like to inherit from. Finally, you can redefine calls for those other classes (in the case of Java interfaces this is partly done for you). However, be very careful if you're using true multiple inheritance: many object-oriented languages (including Smalltalk and Java) don't include full multiple inheritance because it's easy to create horrifically unmaintainable structures. Use this approach only if it really appears to be the simplest and most maintainable approach. A description of various approaches for implementing multiple inheritance in Ada, should you desire it, is included in the Ada Rationale Part Two, section 4.6.


Quiz:

You can create a class to lay out graphical components by creating a class that implements the Java interface "LayoutManager" (which is in the Java package "java.awt"). Let's say say you want to create a "Special_Layout", and you've started as follows:

  with java.lang; use java.lang; -- "Object" type is defined here.
  with java.awt.LayoutManager; use java.awt.LayoutManager;

  package Special_Layout is
    type Special_Layout_Obj is new Object with
      record
        -- SOMETHING
      end record;
    type Special_Layout_Ptr is access all Special_Layout_Obj'Class;
    -- Special_Layout methods go here.
  end Special_Layout;

What should "-- SOMETHING" be replaced with?

  1. LayoutManager : Layout_Manager_Obj;
  2. LayoutManager : Layout_Manager_Ptr;
  3. LayoutManager : aliased LayoutManager_Obj;
  4. LayoutManager : aliased Layout_Manager_Ptr;

You may also:

PREVIOUS Go back to the previous section

NEXT     Skip to the next section

OUTLINE  Go up to lesson 16 outline

David A. Wheeler (dwheeler@dwheeler.com)

The master copy of this file is at "http://www.adahome.com/Tutorials/Lovelace/s16s7.htm".