Flylib.com

Books Software

 
 
 

Section 2.7. Interfaces


2.7. Interfaces

An interface is a classifier that has declarations of properties and methods but no implementations . You can use interfaces to group common elements between classifiers and provide a contract a classifier that provides an implementation of an interface must obey. For example, you can create an interface named Sortable that has one operation named comesBefore(...) . Any class that realizes the Sortable interface must provide an implementation of comesBefore(...) .

Some modern languages, such as C++, don't support the concept of interfaces; UML interfaces are typically represented as pure abstract classes. Other languages, such as Java, do support interfaces but don't allow them to have properties. The moral is that you should be aware of how your model is going to be implemented when modeling your system.

There are two representations for an interface; which one you should use depends on what you're trying to show. The first representation is the standard UML classifier notation with the stereotype «interface» . Figure 2-31 shows the Sortable interface.

Figure 2-31. The Sortable interface

The second representation of an interface is the ball-and-socket notation. This representation shows less detail for the interface but is more convenient for showing relationships to classes. The interface is simply shown as a ball with the name of the interface written below it. Classes dependent on this interface are shown attached to a socket matching the interface. Figure 2-32 shows the Sortable interface using the ball-and-socket notation.

Figure 2-32. Examples of providing and requiring interfaces

Because an interface specifies the contract only for a set of features, you can't instantiate an interface directly. Instead, a class is said to realize an interface if it provides an implementation for the operations and properties. You show realization using a dashed line starting at the realizing classifier and leading to the interface, with a closed arrowhead at the end. Classes that are dependent on the interface are shown using a dashed line with an open arrow (dependency). Figure 2-33 shows a class that realizes the Sortable interface and a class that is dependent on it.

Figure 2-33. Person realizes the Sortable interface and Alphabetizer depends on it

Providing an implementation of an operation is straightforward. You must provide an implementation on a realizing classifier with the same signature as the operation on the interface. Typically there are semantic constraints associated with an operation that must be honored by any implementation. Realizing a property is more subtle. A property on an interface states that any class that realizes the interface must store the data specified by the property in some way . A property on an interface doesn't necessarily mean there will be an associated property on a realizing classifier. However, the classifier must be able to store the data represented by the property and provide a means to manipulate it.



2.8. Templates

Just as interfaces allow you to provide specifications for objects your class will interact with, UML allows you to provide abstractions for the type of class your class may interact with. For example, you can write a List class that can hold any type of object (in C++ this would probably be a void* , in Java and C# it would probably be an Object ). However, while you wanted your List class to be able to support any type of object, you want all of the objects in a given list to be of the same type. UML allows you to create and specify these kinds of abstractions using templates .

You can indicate that a class is a templated (also called parameterized ) class by drawing a dashed rectangle in the upper-right corner of the class. For each element you would like to template, you need to specify a name to act as a placeholder for the actual type. Write the placeholder name in the rectangle. Figure 2-34 shows an example of a List class that can support any type.

Figure 2-34. A templated List class

This example uses ElementType as the name of the templated type for clarity. In practice, this is often abbreviated to just T .


You can have multiple templated types within a single class; just separate the type names with a comma ( , ). If you need to restrict the types the user may substitute, show that with a colon ( : ) followed by the type name. Figure 2-35 shows a more complicated version of the List class that requires a Sorter along with the type of object to store in the list.

Figure 2-35. A templated class with type restrictions

Specifying restrictions on a type that may be used is functionally similar to specifying an interface for a templated member, except that the user may be able to further restrict an instance of your class by specifying a subclass of your type.

When a user creates an instance of a List , she needs to specify the actual type to use in place of ElementType . This is called binding a type to a template. You show binding with the keyword «bind» , followed by a type specification using the following syntax:

<


TemplatedType


->


RealType


>

You can use the binding syntax whenever you refer to a templated class to indicate you want to use a bound version of that class. This is called explicit binding . For example, Figure 2-36 shows a subclass of List called EmployeeList that binds the ElementType of List to a class named Employee .

Figure 2-36. Explicit template binding

The bind keyword also indicates what types should be used with an instance of a template. This is called implicit binding and is shown in Figure 2-37.

Figure 2-37. Implicit template binding