In object-oriented programming, relationships between classes play a crucial role in defining how objects interact with each other. Java, being an object-oriented language, provides mechanisms to model these relationships through association, aggregation, and composition.
- These relationships help model interactions between objects in real-world applications.
- They define the level of dependency and ownership between classes.
- Understanding them improves software design, maintainability, and code reusability.

Association
Association is a relationship between two independent classes where one object uses or interacts with another object. Both objects can exist independently of each other.
- Represents a Uses-A relationship.
- Objects are loosely coupled.
- Both classes can exist independently.
Types of Association
- Unidirectional Association: One class knows about another, but not vice versa. Example: A Student has a LibraryCard, but the LibraryCard doesn't know about the Student.
- Bidirectional Association: Both classes know about and interact with each other. Example: A Teacher is assigned to a Classroom, and the Classroom knows its Teacher.
Example:
import java.io.*;
import java.util.*;
// Class 1
// Bank class
class Bank {
// Attributes of bank
private String bankName;
private Set<Employee> employees;
// Constructor of Bank class
public Bank(String bankName)
{
this.bankName = bankName;
}
// Method of Bank class
public String getBankName()
{
// Returning name of bank
return this.bankName;
}
public void setEmployees(Set<Employee> employees)
{
this.employees = employees;
}
public Set<Employee> getEmployees()
{
return this.employees;
}
}
// Class 2
// Employee class
class Employee {
// Attributes of employee
private String name;
// Constructor of Employee class
public Employee(String name)
{
// this keyword refers to current instance
this.name = name;
}
// Method of Employee class
public String getEmployeeName()
{
// returning the name of employee
return this.name;
}
}
// Class 3
// Association between both the
// classes in main method
class AssociationExample {
// Main driver method
public static void main(String[] args)
{
// Creating Employee objects
Employee emp1 = new Employee("Ridhi");
Employee emp2 = new Employee("Vijay");
// adding the employees to a set
Set<Employee> employees = new HashSet<>();
employees.add(emp1);
employees.add(emp2);
// Creating a Bank object
Bank bank = new Bank("ICICI");
// setting the employees for the Bank object
bank.setEmployees(employees);
// traversing and displaying the bank employees
for (Employee emp : bank.getEmployees()) {
System.out.println(emp.getEmployeeName()
+ " belongs to bank "
+ bank.getBankName());
}
}
}
Output
Ridhi belongs to bank ICICI Vijay belongs to bank ICICI
Explanation: In the above example, two separate classes Bank and Employee are associated through their Objects. Bank can have many employees, So, it is a one-to-many relationship.

Aggregation
Aggregation is a special form of Association that represents a Has-A relationship with weak ownership. The contained object can exist independently of the container object.
- Represents a Has-A relationship.
- It is a weak association.
- Child objects can exist independently of the parent object.

Example:
import java.io.*;
import java.util.*;
// Class 1
// Student class
class Student {
// Attributes of Student
private String studentName;
private int studentId;
// Constructor of Student class
public Student(String studentName, int studentId)
{
this.studentName = studentName;
this.studentId = studentId;
}
public int getstudentId() {
return studentId;
}
public String getstudentName() {
return studentName;
}
}
// Class 2
// Department class
// Department class contains list of Students
class Department {
// Attributes of Department class
private String deptName;
private List<Student> students;
// Constructor of Department class
public Department(String deptName, List<Student> students)
{
this.deptName = deptName;
this.students = students;
}
public List<Student> getStudents() {
return students;
}
public void addStudent(Student student)
{
students.add(student);
}
}
// Class 3
// Institute class
// Institute class contains the list of Departments
class Institute {
// Attributes of Institute
private String instituteName;
private List<Department> departments;
// Constructor of Institute class
public Institute(String instituteName,
List<Department> departments)
{
// This keyword refers to current instance itself
this.instituteName = instituteName;
this.departments = departments;
}
public void addDepartment(Department department)
{
departments.add(department);
}
// Method of Institute class
// Counting total students in the institute
public int getTotalStudentsInInstitute()
{
int noOfStudents = 0;
List<Student> students = null;
for (Department dept : departments) {
students = dept.getStudents();
for (Student s : students) {
noOfStudents++;
}
}
return noOfStudents;
}
}
// Class 4
// main class
class AggregationExample {
// main driver method
public static void main(String[] args)
{
// Creating independent Student objects
Student s1 = new Student("Parul", 1);
Student s2 = new Student("Sachin", 2);
Student s3 = new Student("Priya", 1);
Student s4 = new Student("Rahul", 2);
// Creating an list of CSE Students
List<Student> cse_students = new ArrayList<Student>();
cse_students.add(s1);
cse_students.add(s2);
// Creating an initial list of EE Students
List<Student> ee_students = new ArrayList<Student>();
ee_students.add(s3);
ee_students.add(s4);
// Creating Department object with a Students list
// using Aggregation (Department "has" students)
Department CSE = new Department("CSE", cse_students);
Department EE = new Department("EE", ee_students);
// Creating an initial list of Departments
List<Department> departments = new ArrayList<Department>();
departments.add(CSE);
departments.add(EE);
// Creating an Institute object with Departments list
// using Aggregation (Institute "has" Departments)
Institute institute = new Institute("BITS", departments);
// Display message for better readability
System.out.print("Total students in institute: ");
// Calling method to get total number of students
// in the institute and printing on console
System.out.print(
institute.getTotalStudentsInInstitute());
}
}
Output
Total students in institute: 4
Explanation:
- There is an Institute which has no. of departments like CSE, EE. Every department has no. of students.
- So, we make an Institute class that has a reference to Object or no. of Objects (i.e. List of Objects) of the Department class.
- That means Institute class is associated with Department class through its Object(s).
- And Department class has also a reference to Object or Objects (i.e. List of Objects) of the Student class means it is associated with the Student class through its Object(s).
It represents a Has-A relationship. In the above example: Student Has-A name. Student Has-A ID. Department Has-A Students as depicted from the below media.

Note: Code reuse is best achieved by aggregation.
Composition
Composition is a strong form of Aggregation that represents a Part-Of relationship. In Composition, the lifecycle of the contained object depends completely on the container object.
- Represents a Part-Of relationship.
- Strong ownership exists between objects.
- Child objects cannot exist without the parent object.

Example:
import java.io.*;
import java.util.*;
// Room class
class Room {
private String roomName;
public Room(String roomName) {
this.roomName = roomName;
}
public String getRoomName() {
return roomName;
}
}
// House class
class House {
private String houseName;
private List<Room> rooms;
public House(String houseName) {
this.houseName = houseName;
this.rooms = new ArrayList<>();
}
public void addRoom(Room room) {
rooms.add(room);
}
public List<Room> getRooms() {
return new ArrayList<>(rooms);
}
public int getTotalRooms() {
return rooms.size();
}
}
// Main class
class CompositionExample {
public static void main(String[] args) {
House house = new House("Dream House");
house.addRoom(new Room("Living Room"));
house.addRoom(new Room("Bedroom"));
house.addRoom(new Room("Kitchen"));
house.addRoom(new Room("Bathroom"));
int r = house.getTotalRooms();
System.out.println("Total Rooms: " + r);
System.out.println("Room names: ");
for (Room room : house.getRooms()) {
System.out.println("- " + room.getRoomName());
}
}
}
Output
Total Rooms: 4 Room names: - Living Room - Bedroom - Kitchen - Bathroom
Explanation: In the above example, if the house is destroyed, its room also get destroyed this represents a complete composition relationship, where the room is the part of the house and the life cycle of room completely depends on the house.
Difference Between Association, Aggregation and Composition
Feature | Association | Aggregation | Composition |
|---|---|---|---|
Definition | General relationship between two classes | A special form of association with a "has-a" relationship | A stronger form of association with a "part-of" relationship |
Dependency | Classes are related but can exist independently | Contained objects can exist independently of the container object | Contained objects cannot exist without the container object |
Lifecycle | Independent lifecycles | Independent lifecycles | Dependent lifecycles |
Ownership | No ownership implied | Shared ownership | Exclusive ownership |
Strength | Weak | Moderate | Strong |
Cardinality | One-to-one, one-to-many, many-to-one, many-to-many | One-to-one, one-to-many, many-to-one, many-to-many | One-to-one, one-to-many |
Example | Teacher and Student | Library and Books | Car and Engine |
Representation | Uses a direct reference | Uses a reference to the contained object(s) | Contains instances of the contained object(s) |
Illustrative Example Code | java class | java class | java class |