Chapter 10. Genericity

Important

Genericity

Genericity is the construction of a class C so that one or more of the classes that it uses internally is supplied only at run-time (at the time that an object of class C is instiated)

Problem:

Sometimes you want to write an class that supports "generic" types of classes.

Example: List of something. Provides the same operations, but takes different parameters.

Assume we have the following classes:

Figure 10.1. Two classes that have nothing in common
Two classes that have nothing in common

Unfortunately these two things have nothing in common. So if we want to provide a "Stack" of cars and a "Stack" of People, we'd have to implement two classes:

Figure 10.2. Two different stacks for two different types
Two different stacks for two different types

However, if we look at the functionality they provide, they are actually very similar. As a matter of fact, the implementation of both would be very much the same. If we would replace "Car" or "Person" with a more generic term like "item", we get:

Figure 10.3. Two similar stacks for two different types
Two similar stacks for two different types

Please note, that the only difference between these two classes is now the class on which they operate. One still has "Car", the other one "Person". The actual implementation of the functions will now be exactly the same!

So can we not make a class that somehow has a parameter of which class to operate on?

Yes, we can! (Thats the point of this lecture). These classes are called "Generic classes".

Figure 10.4. A generic Stack Class
A generic Stack Class

UML Notation:

  • A generic is "added on" as an extra box with a dashed outline

  • The format is name : type

  • You can use any name you like

  • The name can be used inside that class like a type

  • In this class, type will always be "Class"

  • Every class may have multiple generics, they each go on their own line.

Note for MagicDraw: In MagicDraw, Generics are called "Template Parameters".

We are now not only specifying one class, but actually a set of classes. Each individual class can only use the data type provided! To use a particular class, we have to provide the template parameter.

Example in C++:

GenericStack<Car> *carStack = new GenericStack<Car>();
GenericStack<Person> *people = new GenericStack<Person>();

Then, using it is easy:

Car *c = new Car();
carStack.addItem(c);
carStack.addItem(new Car());
Person max = new Person();
Person someoneelse = new Person();
people.addItem(max);
people.addItem(someoneelse);

Until your data structures class, you will very likely not write generic classes, but you will use them. C++'s Standard Template Library (STL) provides many very useful generic classes.

For everyone who misliked arrays in C++, there is the generic class "Vector". This class provides:

  • a [] operator for easy access to its elements

  • an operation to add new elements

  • an operations to check the current size

  • an operation to wipe out the contents

  • an operation to check it is empty (convenience for size()==0)

  • a resize operation

  • and many more

Figure 10.5. The STL class "Vector"
The STL class "Vector"

Note: Everytime where we have multiplicity with a given maximum size, you will most likely use static arrays in C++ (example: Car has 4 wheels)

Everywhere where we have multiplicity with a maximum size of * you will most likely use the Vector<T> class.

So whenever you model:

properties : Property [*]

you would actually implement:

properties : Vector<Property>

Note for this class: Always use multiplicity in models, Vector<> in implementation. I do not want to see Vector<> in your model!

Practice:

Draw an UML diagram for a generic class "Set". A set contains elements of a certain class. It should provide operations to add an element, remove an element, check if the set is empty, and check if an element already exists in the set.