Aggregation is a concept in Java that allows one class to contain objects of another class as a member variable. It is a way to achieve a “has-a” relationship between two classes. In Java, aggregation is implemented using object references.
Here’s an example to illustrate aggregation:
public class Address { private String street; private String city; private String state; private String zip; // constructor and getters/setters omitted for brevity } public class Person { private String name; private int age; private Address address; // Aggregation // constructor and getters/setters omitted for brevity }
In this example, the Person
class has an instance variable of type Address
. This is an example of aggregation because a Person
“has-a” Address
.
We can create a Person
object and set its Address
using the following code:
Address address = new Address("123 Main St", "Anytown", "CA", "12345"); Person person = new Person("John Doe", 30, address);
Here, we create an Address
object and pass it to the Person
constructor to set the Person
‘s Address
.
We can also access the Person
‘s Address
using the getter method:
Address personAddress = person.getAddress();
Aggregation is useful for creating more complex objects that are composed of simpler objects. It allows us to create modular, reusable code by separating concerns into different classes.
Simple Example of Aggregation:
Here is a simple example of aggregation in Java:
public class Book { private String title; private String author; private int year; private Publisher publisher; // Aggregation public Book(String title, String author, int year, Publisher publisher) { this.title = title; this.author = author; this.year = year; this.publisher = publisher; } // Getters and setters omitted for brevity } public class Publisher { private String name; private String address; public Publisher(String name, String address) { this.name = name; this.address = address; } // Getters and setters omitted for brevity }
In this example, the Book
class has a reference to an instance of the Publisher
class. The Publisher
class is the simpler object that is being aggregated by the Book
class.
We can create a Book
object and set its Publisher
using the following code:
Publisher publisher = new Publisher("Penguin Random House", "123 Main St, New York"); Book book = new Book("The Great Gatsby", "F. Scott Fitzgerald", 1925, publisher);
Here, we create a Publisher
object and pass it to the Book
constructor to set the Book
‘s Publisher
.
We can also access the Book
‘s Publisher
using the getter method:
Publisher bookPublisher = book.getPublisher();
Aggregation allows us to model more complex relationships between objects. In this example, we can see that a Book
“has-a” Publisher
. By using aggregation, we can create more modular and reusable code that separates concerns into different classes.
When use Aggregation?
Aggregation is typically used when one class needs to reference another class as a member variable, but the two classes have a “has-a” relationship rather than an “is-a” relationship.
Here are some scenarios where aggregation can be used:
- Composition of complex objects: Aggregation can be used to compose complex objects by breaking them down into simpler objects. For example, a
Car
object may have aEngine
object,Wheel
objects, and other components that can be modeled as separate objects. - Separation of concerns: Aggregation allows us to separate concerns into different classes, which can make our code more modular and reusable. For example, a
Person
object may have anAddress
object, which can be reused in other parts of the code. - Managing dependencies: Aggregation can be used to manage dependencies between objects. For example, if a
Database
object needs to use aConnection
object, we can use aggregation to ensure that theConnection
object is created and managed separately from theDatabase
object. - Flexibility: Aggregation can make our code more flexible by allowing us to change the behavior of our program without changing the underlying structure of our classes. For example, we can change the
Publisher
object of aBook
object without changing theBook
class itself.
In general, aggregation is useful when we need to create more complex objects by combining simpler objects, manage dependencies between objects, or separate concerns into different classes. It allows us to create more modular, reusable, and flexible code.
Understanding meaningful example of Aggregation:
Let’s consider an example of an online shopping system, where a customer can place an order for one or more products. Here, we can use aggregation to represent the relationship between an order and its line items.
public class Product { private String name; private double price; public Product(String name, double price) { this.name = name; this.price = price; } // Getters and setters omitted for brevity } public class OrderItem { private Product product; private int quantity; public OrderItem(Product product, int quantity) { this.product = product; this.quantity = quantity; } // Getters and setters omitted for brevity } public class Order { private List<OrderItem> items; private double total; public Order(List<OrderItem> items) { this.items = items; this.total = calculateTotal(); } private double calculateTotal() { double total = 0.0; for (OrderItem item : items) { total += item.getProduct().getPrice() * item.getQuantity(); } return total; } // Getters and setters omitted for brevity }
In this example, the Product
class represents a product available for purchase, the OrderItem
class represents a product that has been added to an order along with its quantity, and the Order
class represents an order that contains one or more OrderItem
s.
The Order
class aggregates a list of OrderItem
objects, which allows us to represent the relationship between an order and its line items. The calculateTotal()
method of the Order
class calculates the total price of the order by summing up the prices of each item in the order.
We can create an order with multiple items using the following code:
Product product1 = new Product("iPhone", 999.0); Product product2 = new Product("MacBook Pro", 1999.0); List<OrderItem> items = new ArrayList<>(); items.add(new OrderItem(product1, 2)); items.add(new OrderItem(product2, 1)); Order order = new Order(items);
In this example, we create two Product
objects and add them to an order with quantities of 2 and 1, respectively. The Order
object is then created by passing the list of OrderItem
objects to its constructor.
By using aggregation, we can create a flexible and modular design that allows us to add or remove products from orders without changing the structure of our classes. We can also reuse the Product
and OrderItem
classes in other parts of our code, which makes our code more modular and easier to maintain.