Newsletter sign-up
View all newsletters

Enterprise Java Newsletter
Stay up to date on the latest tutorials and Java community news posted on JavaWorld

Sponsored Links

Optimize with a SATA RAID Storage Solution
Range of capacities as low as $1250 per TB. Ideal if you currently rely on servers/disks/JBODs

Object-oriented language basics, Part 3

Composition: Build objects from other objects

  • Print
  • Feedback
Suppose your instructor asks you to write a Java application that models cars. According to the instructor's specification, that application must declare an Engine class (that models a car's engine) and a Car class (that models cars) as combinations of makes, models, and manufacturers. Finally, that application must declare a CarDemo class with a main() method that runs the application. And what does main() accomplish? That method creates Car objects (along with an Engine object, for each Car), places appropriate information in each object (via constructor calls), and (for each Car) prints that information in manufacturer, make, model, and engine order. After spending some time writing the application, you end up with Listing 1's source code:

Listing 1. CarDemo.java

// CarDemo.java
class Engine
{
   private String type;
   Engine (String type)
   {
      this.type = type;
   }
   public String getType () { return type; }
}
class Car
{
   private String make;
   private String model;
   private String manufacturer;
   Car (String make, String model, String manufacturer)
   {
      this.make = make;
      this.model = model;
      this.manufacturer = manufacturer;
   }
   public String getMake () { return make; }
   public String getModel () { return model; }
   public String getManufacturer () { return manufacturer; }
}
class CarDemo
{
   public static void main (String [] args)
   {
      Engine e1 = new Engine ("3.8L V6");
      Car c1 = new Car ("Mustang", "Convertible", "Ford");
      Engine e2 = new Engine ("4.6L V8");
      Car c2 = new Car ("Mustang", "GT Coupe", "Ford");
      System.out.println (c1.getManufacturer () + " " +
                          c1.getMake () + " " +
                          c1.getModel () + " " + e1.getType ());
      System.out.println (c2.getManufacturer () + " " +
                          c2.getMake () + " " +
                          c2.getModel () + " " + e2.getType ());
   }
}


Not bad! The source code in Listing 1 meets the aforementioned specification requirements. However, the source code also shows a design problem: Car and Engine are disconnected from each other.

In the real world, it's common to say that a car has an engine, along with tires and other items. In other words, several items, including an engine, compose a car. In contrast, Listing 1 shows that an Engine does not compose a Car, and it is possible to create a Car object without an associated Engine object -- a situation akin to buying a new car without an engine. Why would anyone do that? The error of creating a new Car without an Engine results from both classes being disconnected. The solution to that error is to connect both classes. In Part 3 of this series on object-oriented language basics I will present that solution: composition.

Read the whole series on object-oriented language basics:



What is composition?

In our world, entities compose other entities. For example, a frame, some doors, tires, an engine, a transmission, an exhaust system, and so on compose a vehicle. Because objects serve as software representations of real-world entities, it is possible for several objects to compose another object. The act of composing an object from other objects is known as composition, or aggregation. Consider the following example:

  • Print
  • Feedback

Resources