S06L15 – Composition Introduction

Java Composition Introduction

Table of Contents

1. Introduction to Composition

Composition is a fundamental concept in object-oriented programming (OOP), especially within Java. It enables developers to design complex systems by combining smaller, reusable components into a unified object. While composition is often used alongside inheritance, it serves a distinct purpose. Specifically, inheritance establishes an “is-a” relationship, whereas composition defines a “has-a” relationship, where one object contains other objects.

In this Java Composition Tutorial, we will explore composition in depth, explaining its mechanics, contrasting it with inheritance, and demonstrating how to implement it effectively in Java.

2. Composition vs Inheritance

Feature Composition Inheritance
Relationship “Has-a” (e.g., a car has an engine) “Is-a” (e.g., a car is a vehicle)
Flexibility Highly flexible; components can be swapped at runtime Less flexible; the relationship is static
Code Reusability Promotes modular, reusable design Reuses existing functionality
Dependency Weaker coupling between objects Stronger coupling between classes

Example:

Consider a Car class. It can include several components like Engine, MusicSystem, and SteeringWheel as part of its composition. This means that a car “has an” engine, music system, and steering wheel.

On the other hand, using inheritance, a Car class could inherit from a Vehicle class, establishing that a car “is a” vehicle.

For more details on the differences between composition and inheritance, visit the official Oracle Java tutorials.

3. Key Components of Composition

Composition breaks down a complex object into smaller, manageable components, each possessing its own properties and behaviors. Common examples of composition can be found in everyday objects such as vehicles and computers.

  • Vehicles: A car may include components like a steering wheel, engine, and seats. These components collaborate to form the complete car.
  • Computer Systems: A computer class, such as Laptop, might contain components like a processor, RAM, hard drive, and graphics card.

Each component functions as a separate object with distinct attributes. For instance:

  • Processor: Includes attributes like brand, series, number of cores, and frequency.
  • RAM: Comes in various types such as DDR4, DDR5, and sizes like 8GB, 16GB.

4. Implementing Composition in Java

Now, let’s delve into implementing composition in Java through a practical example. We’ll create a Laptop class that comprises components like Processor, RAM, and HardDrive.

Step-by-Step Explanation

  • Processor Class: Defines a Processor object with properties brand and cores. The method getProcessorDetails() returns a string detailing the processor’s specifications.
  • RAM Class: Defines a RAM object with properties type and sizeGB. The method getRAMDetails() provides RAM details.
  • HardDrive Class: Defines a HardDrive object with properties type and capacity. The method getHardDriveDetails() returns hard drive information.
  • Laptop Class: Contains three fields: Processor, RAM, and HardDrive. This class uses composition by including these objects as fields.
  • Main Class: Creates instances of Processor, RAM, and HardDrive, then composes them into a Laptop object. Finally, it calls displayLaptopDetails() to print the specifications.

Output:

5. When to Use Composition

Composition is a highly flexible approach, often favored over inheritance in various scenarios:

  • Modular Design: Composition enables the creation of small, reusable components that can be easily modified or replaced without affecting the entire system.
  • Avoiding Fragile Base Classes: Inheritance can lead to tightly coupled hierarchies, making the code brittle and harder to maintain. Composition maintains loose coupling, enhancing maintainability.
  • Runtime Flexibility: With composition, objects can be composed and modified at runtime, offering greater adaptability in system design.

Therefore, consider using composition when building systems that require a “has-a” relationship, or when flexibility and reusability are paramount.

6. Conclusion

Composition is a pivotal principle in Java and OOP, enabling the construction of complex objects by integrating simpler components. It offers greater flexibility compared to inheritance and is essential for building modular, maintainable applications. By mastering and effectively applying composition, developers can design scalable and reusable systems that meet modern software development standards.