Composition in Java with Example

Introduction

Composition is a fundamental concept in Object-Oriented Programming (OOP) that allows a class to contain objects of other classes to achieve code reuse and establish a has-a relationship. Unlike inheritance, which represents an is-a relationship, composition models a relationship where one object is made up of one or more objects.

Table of Contents

  1. What is Composition?
  2. Benefits of Composition
  3. Composition vs Inheritance
  4. Example: Composition in Java
  5. Real-World Examples of Composition
  6. Conclusion

1. What is Composition?

Composition is a design principle where a class contains references to one or more objects of other classes. This allows the class to use the functionality of the composed objects and delegate tasks to them. Composition is often preferred over inheritance because it promotes greater flexibility and modularity in the design.

Example: A university consists of several departments. Whenever a university object is destroyed automatically, all the department objects will be destroyed. Without an existing university object, there is no chance of an existing dependent object; hence, these are strongly associated, and this relationship is called composition.

2. Benefits of Composition

  • Reusability: Composition allows for code reuse by including instances of other classes.
  • Flexibility: Changes to composed objects can be made independently of the class that uses them.
  • Encapsulation: Composition encapsulates the functionality of composed objects, reducing dependencies.
  • Better Modeling: Composition better represents real-world relationships where objects are made up of other objects.

3. Composition vs Inheritance

FeatureCompositionInheritance
RelationshipHas-a (one object contains another object)Is-a (one class is a type of another)
FlexibilityMore flexible, allows runtime behavior changesLess flexible, fixed at compile time
CouplingLoosely coupledTightly coupled
ReusabilityPromotes high reusabilityLimited reusability
EncapsulationBetter encapsulationExposes implementation details

4. Example: Composition in Java

Example:

Let's create a Library class that contains multiple Book objects using composition.

Step 1: Define the Book Class

public class Book {
    private String title;
    private String author;

    public Book(String title, String author) {
        this.title = title;
        this.author = author;
    }

    public String getTitle() {
        return title;
    }

    public String getAuthor() {
        return author;
    }
}

Step 2: Define the Library Class

import java.util.ArrayList;
import java.util.List;

public class Library {
    private List<Book> books;

    public Library() {
        this.books = new ArrayList<>();
    }

    public void addBook(Book book) {
        books.add(book);
    }

    public void showBooks() {
        for (Book book : books) {
            System.out.println("Title: " + book.getTitle() + ", Author: " + book.getAuthor());
        }
    }
}

Step 3: Main Class to Demonstrate Composition

public class Main {
    public static void main(String[] args) {
        Book book1 = new Book("1984", "George Orwell");
        Book book2 = new Book("To Kill a Mockingbird", "Harper Lee");

        Library library = new Library();
        library.addBook(book1);
        library.addBook(book2);

        library.showBooks();
        // Output:
        // Title: 1984, Author: George Orwell
        // Title: To Kill a Mockingbird, Author: Harper Lee
    }
}

Explanation:

  • Book: A simple class with title and author attributes.
  • Library: A class that uses composition to include multiple Book objects. The Library class manages a list of books and provides methods to add and display books.
  • Main: A class to demonstrate the use of composition by creating Book objects and adding them to the Library.

5. Real-World Examples of Composition

Example 1: Car and Engine

A Car class can use composition to include an Engine object. The Car class can delegate the starting and stopping functionalities to the Engine class.

class Engine {
    public void start() {
        System.out.println("Engine started.");
    }

    public void stop() {
        System.out.println("Engine stopped.");
    }
}

class Car {
    private Engine engine;

    public Car() {
        this.engine = new Engine();
    }

    public void startCar() {
        engine.start();
        System.out.println("Car started.");
    }

    public void stopCar() {
        engine.stop();
        System.out.println("Car stopped.");
    }
}

public class Main {
    public static void main(String[] args) {
        Car car = new Car();
        car.startCar();  // Output: Engine started. Car started.
        car.stopCar();   // Output: Engine stopped. Car stopped.
    }
}

Example 2: Computer and Components

A Computer class can use composition to include CPU, RAM, and HardDrive objects. The Computer class can delegate the functionalities to these components.

class CPU {
    public void process() {
        System.out.println("CPU processing...");
    }
}

class RAM {
    public void load() {
        System.out.println("RAM loading...");
    }
}

class HardDrive {
    public void readData() {
        System.out.println("HardDrive reading data...");
    }
}

class Computer {
    private CPU cpu;
    private RAM ram;
    private HardDrive hardDrive;

    public Computer() {
        this.cpu = new CPU();
        this.ram = new RAM();
        this.hardDrive = new HardDrive();
    }

    public void startComputer() {
        cpu.process();
        ram.load();
        hardDrive.readData();
        System.out.println("Computer started.");
    }
}

public class Main {
    public static void main(String[] args) {
        Computer computer = new Computer();
        computer.startComputer();
        // Output:
        // CPU processing...
        // RAM loading...
        // HardDrive reading data...
        // Computer started.
    }
}

6. Conclusion

Composition in Java is a powerful concept that promotes code reuse and modularity by allowing a class to contain objects of other classes. It models a has-a relationship, which is more flexible and encapsulated than inheritance. By using composition, developers can build complex systems that are easy to maintain and extend. Understanding and applying composition effectively is essential for designing robust and scalable Java applications.

Happy coding!

Comments