The server-side mapping for interfaces provides an up-call API for the Ice run time: by implementing member functions in a servant class, you provide the hook that gets the thread of control from the Ice server-side run time into your application code.
On the client side, interfaces map to proxy classes (see Section 5.12). On the server side, interfaces map to
skeleton classes. A skeleton is a class that has a pure virtual member function for each operation on the corresponding interface. For example, consider the Slice definition for the
Node interface we defined in
Chapter 5 once more:
•
For each Slice interface <interface‑name>, the compiler generates Java interfaces
_<interface‑name>Operations and
_<interface‑name>OperationsNC (
_NodeOperations and
_NodeOperationsNC in this example). These interfaces contains a member function for each operation in the Slice interface. (You can ignore the
Ice.Current parameter for the time being—we discuss it in detail in
Section 28.6.)
•
For each Slice interface <interface‑name>, the compiler generates a Java interface
<interface‑name> (
Node in this example). That interface extends
Ice.Object and the two operations interfaces.
•
For each Slice interface <interface‑name>, the compiler generates an abstract class
_<interface‑name>Disp (
_NodeDisp in this example). This abstract class is the actual skeleton class; it is the base class from which you derive your servant class.
In order to provide an implementation for an Ice object, you must create a servant class that inherits from the corresponding skeleton class. For example, to create a servant for the
Node interface, you could write:
By convention, servant classes have the name of their interface with an I‑suffix, so the servant class for the
Node interface is called
NodeI. (This is a convention only: as far as the Ice run time is concerned, you can chose any name you prefer for your servant classes.) Note that
NodeI extends
_NodeDisp, that is, it derives from its skeleton class.
As far as Ice is concerned, the NodeI class must implement only a single method: the
name method that it inherits from its skeleton. This makes the servant class a concrete class that can be instantiated. You can add other member functions and data members as you see fit to support your implementation. For example, in the preceding definition, we added a
_name member and a constructor. (Obviously, the constructor initializes the
_name member and the
name function returns its value.)
Whether an operation is an ordinary operation or an idempotent operation has no influence on the way the operation is mapped. To illustrate this, consider the following interface: