One of the fundamental activities of any software system design is establishing relationships between classes. Two fundamental ways to relate classes are inheritance and composition. Although the compiler and Java virtual machine (JVM) will do a lot of work for you when you use inheritance, you can also get at the functionality of inheritance when you use composition. This article will compare these two approaches to relating classes and will provide guidelines on their use.
First, some background on the meaning of inheritance and composition.
About inheritance
In this article, I'll be talking about single inheritance through class extension, as in:
I won't be talking about multiple inheritance of interfaces through interface extension. That topic I'll save for next month's Design Techniques article, which will be focused on designing with interfaces.
Here's a UML diagram showing the inheritance relationship between
About composition
By composition, I simply mean using instance variables that are references to other objects. For example:
The UML diagram showing the composition relationship has a darkened diamond, as in:
Figure 2. The composition relationship
First, some background on the meaning of inheritance and composition.
About inheritance
In this article, I'll be talking about single inheritance through class extension, as in:
class Fruit { //... } class Apple extends Fruit { //... }In this simple example, class
Apple
is related to class Fruit
by inheritance, because Apple
extends Fruit
. In this example, Fruit
is the superclass and Apple
is the subclass. I won't be talking about multiple inheritance of interfaces through interface extension. That topic I'll save for next month's Design Techniques article, which will be focused on designing with interfaces.
Here's a UML diagram showing the inheritance relationship between
Apple
and Fruit
: Figure 1. The inheritance relationship |
By composition, I simply mean using instance variables that are references to other objects. For example:
class Fruit { //... } class Apple { private Fruit fruit = new Fruit(); //... }In the example above, class
Apple
is related to class Fruit
by composition, because Apple
has an instance variable that holds a reference to a Fruit
object. In this example, Apple
is what I will call the front-end class and Fruit
is what I will call the back-end class. In a composition relationship, the front-end class holds a reference in one of its instance variables to a back-end class. The UML diagram showing the composition relationship has a darkened diamond, as in:
Figure 2. The composition relationship