Association in Java | Types, Example
Association in Java is a relationship that defines the relationship between two classes that are independent of one another. It represents Has-A relationship.
Association is one of the core concepts of object-oriented programming in Java. It indicates how objects of classes communicate with each other and how they use the functionality and services provided by that communicated object.
Association establishes a multiplicity relation between objects where all objects have their own lifecycle and there is no owner of association (Has-A relationship).
A multiplicity indicates a number that specifies how many objects of the class are involved in the relationship. Let’s take a real-time example of Teacher and Student to understand the actual meaning of association in Java programming.
Multiple students can connect with a single teacher and a single student can connect with multiple teachers but there is no ownership between objects.
Both teacher and student have their own life cycle. Both can connect and destroy independently.
An association is represented by a solid line between two class objects that describe the relationship.
Types of Relationships Managed by Association in Java
There are the following types of relationships that can be managed by the association in Java. They are as follows:
1. Unidirectional Association:
If an object associates with another object, it is called unidirectional association. It is also called one-way relationship.
For example, a department in college can have many students but vice versa is not possible. This is an unidirectional in nature. A tennis player has a racket. It is an unidirectional association because a racket cannot have tennis player.
2. Bidirectional Association:
When objects involved in association communicate with each other, it is called bidirectional association. A very common example of bidirectional relationship is “Person and Address”. We can have bidirectional many-to-many relationship between person and address objects.
In other words, a person can have associated with multiple addresses and an address can belong to multiple people. This shows the many-to-many relationship.
Association can also establish relationships like one-to-one, one-to-many, many-to-one, and many-to-many relationships. Let’s understand each one with the help of realtime examples.
1. A very common example of one-to-one relationship is “A person can have only one passport”.
2. A very good example of one-to-many relationship is “College and Students”. A college can have many students. Another example of one-to-many relationship is “Bank and Employees”. A bank can have many working employees.
3. An example of many-to-one relationship is “State and Cities”. A state can have many cities, but all the cities are related to that single state.
4. A very common example of many-to-many relationship is “Teachers and Students”. A single student can associate with many teachers, and many students can also associate with a single teacher. Since both can be created or deleted independently therefore, it represents the many-to-many relationship.
Association Example Programs
Let’s take an example program in which we will implement one-to-one relationship under bidirectional association.
Example 1:
public class Person
{
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class Passport
{
private int passportNo;
public int getPassportNo() {
return passportNo;
}
public void setPassportNo(int passportNo) {
this.passportNo = passportNo;
}
}
public class OneToOneTest {
public static void main(String[] args)
{
Person p1 = new Person();
p1.setName("John");
Person p2 = new Person();
p2.setName("Shubh");
Passport pp1 = new Passport();
pp1.setPassportNo(1234567);
Passport pp2 = new Passport();
pp2.setPassportNo(12398576);
// Association between two classes in the main method.
System.out.println(p1.getName()+ " has a US passport whose passport no is: " +pp1.getPassportNo());
System.out.println(p2.getName()+ " has an Indian passport whose passport no is: " +pp2.getPassportNo());
}
}
Output: John has a US passport whose passport no is: 1234567 Shubh has an Indian passport whose passport no is: 12398576
In the preceding example program, the association between Person and Passport is accomplished in the main method and shows one-to-one relationship.
Let’s take an example program in which we will implement many-to-many relationship under bidirectional association.
Example 2:
public class Person
{
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class Address
{
private String state;
private String city;
private String zip;
public String getState() {
return state;
}
public String getCity() {
return city;
}
public String getZip() {
return zip;
}
public void setState(String state) {
this.state = state;
}
public void setCity(String city) {
this.city = city;
}
public void setZip(String zip) {
this.zip = zip;
}
}
public class OneToOneTest {
public static void main(String[] args)
{
Person p1 = new Person();
p1.setName("John");
Person p2 = new Person();
p2.setName("Shubh");
Address a1 = new Address();
a1.setState("Jharkhand");
a1.setCity("Dhanbad");
a1.setZip("123524");
Address a2 = new Address();
a2.setState("Maharashtra");
a2.setCity("Mumbai");
a2.setZip("123635");
// Association between two classes in the main method.
System.out.println(p1.getName()+ " lives at address " +a1.getCity()+ "' " +a1.getState()+ ", " +a1.getZip()+ " but he has also address at " +a2.getCity()+ ", " +a2.getState()+ ", "+a2.getZip());
System.out.println(p2.getName()+ " lives at address " +a2.getCity()+ "' " +a2.getState()+ ", " +a2.getZip()+ " but she has also address at " +a1.getCity()+ ", " +a1.getState()+ ", "+a1.getZip());
}
}
Output: John lives at address Dhanbad' Jharkhand, 123524 but he has also address at Mumbai, Maharashtra, 123635 Shubh lives at address Mumbai' Maharashtra, 123635 but she has also address at Dhanbad, Jharkhand, 123524
In this example program, the association between Person and Address is accomplished in the main method and shows a bidirectional many-to-many relationship.
Types of Association in Java
There are two combinations of association possible in Java that are as follows:
- Aggregation
- Composition
a) Aggregation:
An aggregation is a special form of unidirectional association that represents an ownership relationship between two objects.
That is, two aggregated objects have their own life cycles but one of the objects is the owner of the Has-A relationship. It is often referred to as a part-of relationship.
For example, the association between a car and the passengers in the car is aggregation. Passengers can be the owner of car. Both have their own life cycle but one of the passengers can be the owner of car. Here, car is a part-of relationship.
You will learn in more detail about aggregation with example programs in the next tutorial.
b) Composition:
A composition is a special and more restrictive form of aggregation. It also represents Has-A relationship where an object cannot exist on its own. The “whole” is actually dependent on the “part”.
For example, the association between a car and its engine represents composition. Since a car cannot exist without an engine.
We will know in more detail about composition in the further tutorial with real-time example programs.
Benefits of Association in Java
There are several advantages of using association in Java programming:
- Classes remain separate and manageable, enhancing code structure. The code becomes more modular and easier to understand.
- We can reuse the classes in different contexts by establishing associations. It reduces redundancy and enhances code reusability.
- Association provides flexibility, as we can accommodate modifications in one class without affecting the entire system.
- Interaction between classes is controlled, improving security.
Best Practices for Utilizing Association
There are the following key points that you should keep in mind when you implement an association between classes.
- Clearly define the purpose of the association between classes so that the relationship is meaningful and aligns with the overall design..
- Use meaningful class and method names that reflect the nature of the association. This makes the code more readable and understandable.
- Avoid excessive coupling between associated classes.
- Understand the cardinality of the relationship (one-to-one, one-to-many, many-to-many).
- Do not try to overcomplicate relationships between classes.
- Use unit testing to verify the behavior of associated classes.
- Debug by tracing the flow of data and interactions between associated classes.