Has-A Relationship in Java with Example

In addition to Uses-A relationship and Is-A relationship that represents inheritance, one more relationship is commonly used in object-oriented programming. This relationship is called Has-A relationship in Java.

When an object of one class is created as a data member inside another class, it is called Has-A relationship. In other words, a relationship in which an object of one class has a reference to an object of another class or another instance of the same class is called Has-A relationship.

Let’s understand Has-A relationship with the help of some real-time examples.

Has-A Relationship Realtime Examples


1. A most common real-time example of Has-A relationship in Java is “A person has an address”.

Has-A relationship denotes a whole-part relationship where a part cannot exist without the whole. In the above example, the person represents the whole, and the address represents the part. A part cannot exist by itself.

In Java, there is no special feature by which we can identify the Has-A relationship in the code.

Person class has an instance variable of type Address, as shown in the below code. An instance of Address class is created outside of Person class.

public class Address {
  // Code goes here.
}
public class Person {
// Person has-a Address.
   Address addr = new Address();

// Other codes go here.
}

Look at the above figure where an object of class Address is created as a data member inside another class Person. This relationship is known as Has-A relationship.

An example of Has-A Relationship in Java

In Java, there is no such keyword that implements a Has-A relationship. But we mostly use new keywords to implement a Has-A relationship in Java. Let’s take another common example to understand Has-A relationship.

2. We know that a CPU is part of the computer. We can also rephrase this relationship as “A computer has a CPU”. Does the existence of CPU outside a computer make any sense?

The answer is no. The existence of a CPU makes sense only within the computer. So, a computer and CPU represent the whole-part relationship.

Look at the below code to understand better.

public class CPU {
   // Code goes here.
}
public class Computer {
 // CPU part-of Computer.
    private CPU cpu = new CPU();

 // Other codes go here.
}

3. We know that a brain has a thought. Thought cannot exist without the existence of the brain. The code is given below:

public class Thought {
  // Code goes here.
}
public class Brain {
  Thought thought = new Thought();

// Other codes go here.
}

4. We know about a special class known as inner class in Java that can also be used to represent Has-A relationship. An instance of inner class can exist only inside an instance of its outer class (enclosing class). The outer class would be the whole and the inner class would be the part.

How to Decide Which Type of Relationship We Need?


We know that relationships between objects make all the differences in object-oriented programming. The most important relationships are Is-A relationship and Has-A relationship.


The best way to decide which kind of relationship we need is as follows:

a) If your problem with a phrase contains ” . . . . is a . . . .”. Then, you should use Is-A relationship (Inheritance). For example, “A dog is a pet”. We cannot say “A dog has a pet”, as makes no sense at all. So, in this case, we will create a superclass named Pet and a derived subclass named Dog.

b) On the other hand, if your problem with a phrase like this: “A pet has a name”, then use has-a relationship. This is because if we use Is-A relationship instead of Has-A relationship, then the statement will be like this: “A dog is a name”. This statement makes no sense at all.

From all the above examples, you will have understood which kind of relationship you need in your code.

Types of Has-A Relationship in Java


There are two types of Has-A relationship that are as follows:

a. Aggregation
b. Composition

Aggregation: Aggregation is one of the core concepts of object-oriented programming. It focuses on establishing a Has-A relationship between two classes.

In other words, two aggregated objects have their own life cycle, but one of the objects has an owner of Has-A relationship and child object cannot belong to another parent object. For example, a library has students. If the library is destroyed, students will exist without library.

Composition: Composition is another one of the core concepts of object-oriented programming. It focuses on establishing a strong Has-A relationship between the two classes.

In other words, two composited objects cannot have their own life cycle. That is, a composite object cannot exist on its own. If one composite object is destroyed, all its parts are also be deleted.

For example, a house can have multiple rooms. A room cannot exist independently, and any room cannot belong to two different houses. If the house is destroyed, all its rooms will be automatically destroyed.

Has-A Relationship Example Programs


Let’s take some example programs based on the Has-A relationship in Java.

Example 1:

package javaPrograms;
// Define the Address class
class Address {
   private String street;
   private String city;
   private String state;
   private String zipCode;

// Define a constructor.
   public Address(String street, String city, String state, String zipCode) {
       this.street = street;
       this.city = city;
       this.state = state;
       this.zipCode = zipCode;
   }
   public String getAddressInfo() {
       return street + ", " + city + ", " + state + " " + zipCode;
   }
}
// Define the Person class using composition
class Person {
   private String name;
   private Address address; // Has-A relationship with Address

   public Person(String name, Address address) {
       this.name = name;
       this.address = address;
   }
   public String getPersonInfo() {
        return "Name: " + name + "\nAddress: " + address.getAddressInfo();
   }
}
public class Main {
public static void main(String[] args) 
{
 // Create an Address instance.
    Address personAddress = new Address("123 Main St", "Cityville", "Stateville", "12345");

 // Create a Person instance with the Address instance.
    Person person = new Person("John Doe", personAddress);

 // Display person's information.
    System.out.println(person.getPersonInfo());
  }
}
Output:
       Name: John Doe
       Address: 123 Main St, Cityville, Stateville 12345

In this example, we have created two classes: Address and Person. The Address class represents a street address with components like street, city, state, and zip code. The Person class has a “Has-A” relationship with the Address class, as each person has an associated address.

The getPersonInfo() method defined in the Person class provides a formatted output of the person’s name and address. As you can see in this example, how the “Has-A” relationship allows us to create more complex objects by combining simpler classes.

Example 2:

package javaPrograms;
// Define the Engine class
class Engine {
    private String type;

    public Engine(String type) {
        this.type = type;
    }

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

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

// Define the Car class using composition
class Car {
    private String model;
    private Engine engine; // Has-A relationship with Engine

    public Car(String model, Engine engine) {
        this.model = model;
        this.engine = engine;
    }

    public void startCar() {
        System.out.println("Starting the car with model: " + model);
        engine.start();
    }

    public void stopCar() {
        System.out.println("Stopping the car with model: " + model);
        engine.stop();
    }
}

public class Main {
public static void main(String[] args) 
{
  // Create an Engine instance.
     Engine carEngine = new Engine("V6");

  // Create a Car instance with the Engine instance.
     Car myCar = new Car("Sedan", carEngine);

  // Call methods to start and stop car.
     myCar.startCar();
     myCar.stopCar();
  }
}
Output:
       Starting the car with model: Sedan
       Engine started.
       Stopping the car with model: Sedan
       Engine stopped.

In this example, we have defined two classes: Engine and Car. The Engine class represents an engine with start() and stop() methods. The Car class has a “Has-A” relationship with the Engine class because it contains an instance of the Engine class as one of its arguments.

This composition allows us to construct a Car object that has an associated Engine. The methods of Car class can interact with the methods of Engine class through this relationship.

Advantages of Using the “Has-A” Relationship


When employed effectively, the “Has-A” relationship provides several advantages to our Java code:

  • By breaking down complex systems into smaller, manageable components, our code becomes more modular and easier to understand.
  • We can reuse existing classes in different contexts. It reduces redundancy and enhances code reusability.
  • Encapsulation enhances because each class is responsible for its own functionality, contributing to the overall maintainability of the codebase.
  • The ability to change the components within a class without affecting its external behavior offers flexibility and adaptability to our code.