Aggregation is a key concept in object-oriented programming (OOP) that represents a "has-a" relationship between two classes, but with a crucial distinction: the lifecycle of the contained object is independent of the container object. This means that while one class contains another, the contained object can exist independently of the container.
Aggregation allows for better modularity, code reuse, and maintainability. It is different from composition, where the contained object cannot exist without the container.
Aggregation is a form of association in OOP where an object of one class contains a reference to an object of another class. However, the contained object can exist independently of the container. This means that even if the container object is destroyed, the contained object can still be used elsewhere in the application.
- Represents a has-a relationship.
- The contained object can exist independently of the container.
- Implemented using references (pointers) to objects.
- Promotes loose coupling between objects.
Consider a scenario where a University
contains multiple Professor
objects. However, a Professor
can exist independently of any university. This is an example of aggregation.
class Professor {
private String name;
private String subject;
public Professor(String name, String subject) {
this.name = name;
this.subject = subject;
}
public void teach() {
System.out.println(name + " is teaching " + subject);
}
}
class University {
private String universityName;
private List<Professor> professors;
public University(String universityName) {
this.universityName = universityName;
this.professors = new ArrayList<>();
}
public void addProfessor(Professor professor) {
professors.add(professor);
}
public void showProfessors() {
System.out.println("Professors at " + universityName + ":");
for (Professor professor : professors) {
System.out.println(" - " + professor.name);
}
}
}
import java.util.*;
public class AggregationExample {
public static void main(String[] args) {
Professor prof1 = new Professor("Dr. Smith", "Computer Science");
Professor prof2 = new Professor("Dr. Johnson", "Mathematics");
University university = new University("Harvard University");
university.addProfessor(prof1);
university.addProfessor(prof2);
university.showProfessors();
// Professors can exist independently
prof1.teach();
prof2.teach();
}
}
Professors at Harvard University:
- Dr. Smith
- Dr. Johnson
Dr. Smith is teaching Computer Science
Dr. Johnson is teaching Mathematics
Feature | Aggregation | Composition |
---|---|---|
Relationship | "Has-a" | "Has-a" |
Ownership | Contained object can exist independently | Contained object cannot exist without the container |
Lifetime | Contained object outlives the container | Contained object is destroyed with the container |
Example | University and Professors | Car and Engine |
- Aggregated objects can be used in multiple places without being tightly coupled to a single container class.
- Aggregation allows objects to interact without being dependent on the lifecycle of each other.
- Changes in one class do not heavily impact the other, making the codebase easier to modify and extend.
- Many real-world relationships, such as a school and its teachers, a company and its employees, naturally fit the aggregation model.
Using interfaces, we can further enhance the flexibility of aggregation.
interface Teachable {
void teach();
}
class Professor implements Teachable {
private String name;
private String subject;
public Professor(String name, String subject) {
this.name = name;
this.subject = subject;
}
public void teach() {
System.out.println(name + " is teaching " + subject);
}
}
class University {
private String universityName;
private List<Teachable> professors;
public University(String universityName) {
this.universityName = universityName;
this.professors = new ArrayList<>();
}
public void addProfessor(Teachable professor) {
professors.add(professor);
}
public void showProfessors() {
System.out.println("Professors at " + universityName + ":");
for (Teachable professor : professors) {
professor.teach();
}
}
}
import java.util.*;
public class InterfaceAggregationExample {
public static void main(String[] args) {
Professor prof1 = new Professor("Dr. Adams", "Physics");
Professor prof2 = new Professor("Dr. Lee", "Chemistry");
University university = new University("MIT");
university.addProfessor(prof1);
university.addProfessor(prof2);
university.showProfessors();
}
}
Professors at MIT:
Dr. Adams is teaching Physics
Dr. Lee is teaching Chemistry
- When an object can exist independently from the container.
- When designing loosely coupled systems.
- When different objects need to be shared across multiple containers.
- When following SOLID principles, particularly the Dependency Inversion Principle (DIP).