1
Aggregation, Composition, and Inheritance
Composition
Aggregation
UML Class Diagram for Composition
and Aggregation
Composition
Prior to this chapter, all of our objects have
been relatively simple, so we've been able to
describe each object with just a single class.
But for an object that's more complex, you
should consider breaking up the object into its
constituent parts and defining one class as the
whole and other classes as parts of the whole.
When the whole class is the exclusive owner of
the parts classes, then that class organization is
called a composition.
Composition
The concept of composition is not new; that's what we do
to describe complex objects in the real world:
Every living creature and most manufactured products are
made up of parts. Often, each part is a subsystem that is
itself made up of its own set of subparts. Together, the
whole system forms a composition hierarchy.
Note the human body composition hierarchy on the next
slide.
Remember that with a composition relationship, a
component part is limited to just one owner at a time. For
example, a heart can be in only one body at a time.
Composition
A partial composition hierarchy for the human body:
Aggregation
In a composition hierarchy, the relationship between a
containing class and one of its part classes is known as a
has-a relationship. For example, each human body has a
brain and has a heart.
There's another has-a relationship, called aggregation, which
is a weaker form of composition. With aggregation, one
class is the whole and other classes are parts of the whole
(as with composition), but there is no additional constraint
that requires parts to be exclusively owned by the whole.
An aggregation example where the parts are not exclusively
owned by the whole
You can implement a school as an aggregation by creating a
whole class for the school and part classes for the different
types of people who work and study at the school.
The people arent exclusively owned by the school because a
person can be part of more than one aggregation.
For example, a person can attend classes at two different
schools and be part of two school aggregations. The same
person might even be part of a third aggregation, of a different
type, like a household aggregation.
Multiplicity
Each class involved in a relationship may specify a
multiplicity. A multiplicity could be a number or an
interval that specifies how many of the classs objects
are involved in the relationship.
The character * means an unlimited number of
objects, and the interval m..n means that the number
of objects should be between m and n, inclusive.
Each student has only one address, and each address
may be shared by up to 3 students. Each student has
one name, and a name is unique for each student.
A student has a name is a composition relationship
between the Student class and the Name class,
whereas a student has an address is an aggregation
relationship between the Student class and the Address
class, because an address may be shared by several
students.
In UML notation, a filled diamond is attached to an
aggregating class (e.g., Student) to denote the
composition relationship with an aggregated class (e.g.,
Name), and an empty diamond is attached to an
aggregating class (e.g., Student) to denote the
Aggregation may exist between objects of the
same class. For example, a person may have a
supervisor.
Car Dealership Program
Suppose you're trying to model a car dealership with a
computer program. Since the car dealership is made
from several distinct non-trivial parts, it's a good
candidate for being implemented with composition and
aggregation relationships.
The car dealership's "non-trivial parts" are a group of
cars, a sales manager, and a group of sales people.
In implementing the program, define four classes:
The Car, Manager, and SalesPerson classes implement the
car dealership's non-trivial parts.
The Dealership class contains the three parts classes.
For each of the three class relationships, DealershipCar, Dealership-SalesPerson, and Dealership-Manager,
is the relationship composition or aggregation?
UML Class Diagram for Composition and
Aggregation
Universal Modeling Language (UML) class diagrams show the
relationships between a program's classes:
A solid line between two classes represents an association a
relationship between classes.
On an association line, a solid diamond indicates a composition
relationship, and a hollow diamond indicates an aggregation
relationship. The diamond goes next to the container class.
The labels on the association lines are called multiplicity values. They
indicate the number of object instances for each of the two connected
classes.
The * multiplicity value represents any size number, zero through infinity.
Car Dealership Program
To implement a program that uses aggregation and
composition:
Define one class for the whole and define separate classes for
each of the parts.
For a class that contains another class, declare an instance
variable inside the containing class such that the instance variable
holds a reference to one or more of the contained class's objects.
Typically, for association lines with * multiplicity values, use an
ArrayList to implement the instance variable associated with the
asterisked class.
If two classes have an aggregation relationship with non-exclusive
ownership, then store the contained class's object in an instance
variable in the containing class, but also store it in another
variable outside of the containing class, so the object can be
added to another aggregation and have two different "owners."
If two classes have a composition relationship, then store the
contained class's object in an instance variable in the containing
class, but do not store it elsewhere. That way, the object can have
only one "owner."
Car Dealership Program
/*************************************************************
* [Link]
* Dean & Dean
*
* This represents an auto retail sales organization.
*************************************************************/
import [Link];
public class Dealership
{
private String company;
private Manager manager;
private ArrayList<SalesPerson> people = new ArrayList<SalesPerson>();
private ArrayList<Car> cars = new ArrayList<Car>();
//**********************************************************
public Dealership(String company, Manager manager)
{
[Link] = company;
[Link] = manager;
}
Car Dealership Program
//**********************************************************
public void addCar(Car car)
{
[Link](car);
}
public void addPerson(SalesPerson person)
{
[Link](person);
}
//**********************************************************
public void printStatus()
{
[Link](company + "\t" + [Link]());
for (SalesPerson person : people)
[Link]([Link]());
for (Car car : cars)
[Link]([Link]());
} // end printStatus
} // end Dealership class
10
Car Dealership Program
/*************************************************************
* [Link]
* Dean & Dean
*
* This class implements a car.
*************************************************************/
public class Car
{
private String make;
//**********************************************************
public Car(String make)
{
[Link] = make;
}
//**********************************************************
public String getMake()
{
return make;
}
} // end Car class
11
Car Dealership Program
/*************************************************************
* [Link]
* Dean & Dean
*
* This class implements a car dealership sales manager.
*************************************************************/
public class Manager
{
private String name;
//**********************************************************
public Manager(String name)
{
[Link] = name;
}
//**********************************************************
public String getName()
{
return name;
}
} // end Manager class
12
Car Dealership Program
/*************************************************************
* [Link]
* Dean & Dean
*
* This class implements a car sales person
*************************************************************/
public class SalesPerson
{
private String name;
private double sales = 0.0; // sales to date
//**********************************************************
public SalesPerson(String name)
{
[Link] = name;
}
//**********************************************************
public String getName()
{
return name;
}
} // end SalesPerson class
13
Car Dealership Program
/************************************************************
* [Link]
* Dean & Dean
*
* This class demonstrates car dealership composition.
************************************************************/
public class DealershipDriver
{
public static void main(String[] args)
{
Manager ahmed = new Manager("Ahmed Abdi");
SalesPerson ash = new SalesPerson("Ash Lawrence");
SalesPerson jeffrey = new SalesPerson("Jeffrey Leung");
Dealership dealership = new Dealership("OK Used Cars", ahmed);
[Link](ash);
[Link](jeffrey);
[Link](new Car("GMC"));
[Link](new Car("Yugo"));
[Link](new Car("Dodge"));
[Link]();
} // end main
} // end DealershipDriver class
14
Aggregation, Composition, and Inheritance
Compared
We've covered two basic types of class
relationships:
Aggregation and composition relationships are when one
class is a whole and other classes are parts of that whole.
An inheritance relationship is when one class is a more
detailed version of another class. The more detailed class
is a subclass, and the other class is a superclass. The
subclass inherits the superclass's members (variables and
methods).
We call aggregation and composition relationships
"has a" relationships because one class, the
container class, has a component class inside of it.
We call an inheritance relationship an "is a"
relationship because one class, a subclass, is a
more detailed version of another class.
34
Aggregation, Composition, and Inheritance
Combined
In the real world, it's fairly common to have
aggregation, composition, and inheritance relationships
in the same program.
For example, what sort of inheritance relationship
could/should be added to our earlier Dealership
program, shown below?
35
Card Game Program
Provide a class diagram for a card game program:
Assume it's a game like war or gin rummy where you have a
deck of cards and two players.
Decide on appropriate classes. For each class, draw a UMLnotation three-partition rectangle and put the class name in
the top partition.
Look for composition relationships between classes. For each
pair of classes related by composition, draw a composition
connecting line with a diamond next to the containing class.
For example, the left composition association line below is for
Game, the containing class, and Deck, the contained class.
36
Card Game Program
Provide a class diagram for a card-game
program (continued):
For each class, decide on appropriate instance
variables and put them in the middle partition of the
class's rectangle.
For each class, decide on appropriate public methods
and put their declarations in the bottom partition of
the class's rectangle.
Look for common instance variables and methods. If
two or more classes contain a set of common
instance variables and/or methods, implement a
superclass and move the common entities to the
superclass. For each subclass/superclass pair, draw
an arrow from the subclass to the superclass to
indicate an inheritance relationship.
37
39
Card Game Program
inheritance
implementation
public class Deck extends GroupOfCards
public class Deck
{
composition
implementati
on
public static final int
TOTAL_CARDS = 52;
{
public static final int
GroupOfCards groupOfCards =
new GroupOfCards();
TOTAL_CARDS = 52;
public Deck()
public Deck()
{
for (int i=0; i<TOTAL_CARDS; i++)
for (int i=0; i<TOTAL_CARDS; i++)
{
[Link](
addCard(
new Card((2 + i%13), i/13));
new Card((2 + i%13), i/13));
}
} // end constructor
} // end constructor
...
...
} // end class Deck
} // end class Deck
Card Game Program
Here's a main method for the card game
program:
public static void main(String[] args)
{
Scanner stdIn = new Scanner([Link]);
String again;
Game game;
do
{
game = new Game();
[Link]();
[Link]("Play another game (y/n)?: ");
again = [Link]();
} while ([Link]("y"));
} // end main
40
Card Game Program
Here's a playAGame method for the Game class:
public void playAGame()
{
Card card;
[Link]();
while ([Link]() > 0)
{
card = [Link]();
[Link](card);
card = [Link]();
[Link](card);
}
...
} // end playAGame
41