Has-A Relationship in Java

In addition to the Uses-A relationship and the 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 declared as a data member (instance variable) inside another class, it is called a Has-A relationship. In other words, a relationship in which one class contains a reference to an object of another class (or sometimes the same class) is known as a Has-A relationship.

The Has-A relationship is mainly used to achieve composition and aggregation in Java. Let us understand the Has-A relationship with the help of some real-world examples.

Has-A Relationship Realtime Examples


1. Person Has an Address

A most common real-time example of Has-A relationship in Java is “A person has an address”. The Has-A relationship represents that one class contains a reference to another class as its member.

Let’s take a simple example of the Has-A relationship in which the Person class contains an object of the Address class.

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

// Other codes go here.
}

In the above code, an object of class Address is declared as a data member inside another class Person. Therefore, this relationship is known as a Has-A relationship.

An example of Has-A Relationship in Java

In Java, there is no special feature by which we can identify or implement the Has-A relationship in the program. We usually create objects using the new keyword and store their references as instance variables.

2. Computer Has a CPU

We know that a CPU is an essential 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. This is a stronger Has-A relationship and is a good example of composition.

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

 // Other codes go here.
}

In this example code, the Computer class contains a CPU object. Therefore, it represents a Has-A relationship in Java.

3. Brain Has a Thought

We know that a brain has a thought. Thought cannot exist without the existence of the brain.

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

// Other codes go here.
}

Here, the Brain class contains a Thought object, so it represents a Has-A relationship.

How to Decide Which Type of Relationship We Need?


Relationships between objects plays an important role in object-oriented programming. The two most common relationships are:

  • Is-A relationship
  • Has-A relationship

The best way to decide which type of relationship to use is as follows:

a) Use Is-A Relationship (Inheritance)

If your problem with a phrase contains ” . . . . is a . . . .”, you should use an 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) Use Has-A Relationship

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

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 main types of Has-A relationship in object-oriented programming:

  • Aggregation
  • Composition

1. Aggregation

Aggregation is one of the core concepts of object-oriented programming. It establishes a weak Has-A relationship between two classes. In other words, aggregation represents a loose coupling between objects.

In aggregation, both objects can exist independently because they have their own life cycles. One object of the class contains a reference to another object of the class, but the contained object is not strongly dependent on the owner object.

For example, a library has students. If the Library object is destroyed, the Student objects can still exist independently.

2. Composition

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

In composition, both composited objects cannot have their own life cycle. The contained object strongly depends on the container object. It cannot exist on its own. In other words, the child object cannot exist independently without the parent object. If the parent object is destroyed, the child objects are also destroyed.

For example, a house can have multiple rooms. A Room generally does not exist independently without a House. If the House object is destroyed, its Room objects are also destroyed because their life cycle depends on the house.

Has-A Relationship Example Programs


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

Example 1:

// 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:

// 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 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.
DEEPAK GUPTA

DEEPAK GUPTA

Deepak Gupta is the Founder of Scientech Easy, a Full Stack Developer, and a passionate coding educator with 8+ years of professional experience in Java, Python, web development, and core computer science subjects. With strong expertise in full-stack development, he provides hands-on training in programming languages and in-demand technologies at the Scientech Easy Institute, Dhanbad.

He regularly publishes in-depth tutorials, practical coding examples, and high-quality learning resources for both beginners and working professionals. Every article is carefully researched, technically reviewed, and regularly updated to ensure accuracy, clarity, and real-world relevance, helping learners build job-ready skills with confidence.