Each instance variable is a reference variable.
One can point to a Cone
object
the other can point to a Cylinder
object.
(But the objects do not exist until they are constructed later in the constructor for Tree
.)
public class Tree { // instance variables private double x, y, z; private Cone branches; private Cylinder trunk; ... }
A Tree
is composed of a Cone
and a Cylinder
.
This is coded by including a reference variable for each of these object types.
At run-time there will be three objects: a Tree
object,
a Cone
object,
and a Cylinder
object.
Even though there are three discrete objects, you think of the tree as one thing composed of three smaller objects. When the program is running these are implemented as three separate blocks of main memory and may be at widely separated locations.
Object composition is sometimes called a has-a relationship between objects:
Tree
has-a Cone
Tree
has-a Cylinder
It is tempting to think that the Cone
and Cylinder
objects are directly part of the Tree
object:
that a complete Cone
object and complete Cylinder
object
are embedded in the Tree
object.
Avoid that thought! All that a Tree
object has is a reference to a Cone
and a reference to a Cylinder
.
Unfortunately, programmers (and books) often speak as if objects directly contained other objects.
In the real-world, this is true. A tree directly consists of branches and trunk.
But in Java, a tree consists of a pointer to the branches and a pointer to a trunk
(and some variables of an integer type.)
Think about what the constructor for a Tree
looks like.
public class Tree { // instance variables private double x, y, z; private Cone branches; private Cylinder trunk; // constructor public Tree( ? ) ... }
Constructors for Cone
and Cylinder
look like this:
public Cone ( double radius, double height ) public Cylinder( double radius, double height )