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:
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:
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:
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".
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
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.