February 11, 2025

Is-A vs Has-A vs Association vs Composition vs Multiple & Multilevel Inheritance

When designing object-oriented systems, understanding relationships between classes is crucial. Terms like Is-A, Has-A, Association, Composition, Multiple Inheritance, and Multilevel Inheritance often create confusion. Whether you're a beginner or have 15 years of experience, this blog will provide a detailed yet easy-to-understand explanation with examples, along with insights into SOLID principles, Design Patterns from Head First Design Patterns, and best practices for future-proof design.




1. Is-A Relationship (Inheritance)

Definition:

An "Is-A" relationship is based on inheritance. It means one class is a subtype of another class, forming a hierarchy.

Example:

A Dog is an Animal, so it inherits behavior from Animal.

class Animal {
    void makeSound() {
        System.out.println("Animal makes a sound");
    }
}

class Dog extends Animal {
    void bark() {
        System.out.println("Dog barks");
    }
}

public class Main {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.makeSound(); // Inherited from Animal
        dog.bark();      // Dog-specific behavior
    }
}

2. Has-A Relationship (Composition & Aggregation)

Definition:

A "Has-A" relationship means one class contains another class as a field, forming a dependency. This is called composition or aggregation.

Example 1 (Composition - Strong Relationship):

A Car has an Engine. The engine is tightly coupled with the car and cannot exist independently.

class Engine {
    void start() {
        System.out.println("Engine starts");
    }
}

class Car {
    private Engine engine;
    
    Car() {
        engine = new Engine(); // Strong relationship (Composition)
    }
    
    void startCar() {
        engine.start();
        System.out.println("Car is running");
    }
}

public class Main {
    public static void main(String[] args) {
        Car car = new Car();
        car.startCar();
    }
}

Example 2 (Aggregation - Weak Relationship):

A Library has Books, but if the library is destroyed, books can still exist.

class Book {
    private String title;
    
    Book(String title) {
        this.title = title;
    }
    
    void display() {
        System.out.println("Book: " + title);
    }
}

class Library {
    private List<Book> books;
    
    Library(List<Book> books) {
        this.books = books; // Weak relationship (Aggregation)
    }
    
    void showBooks() {
        for (Book book : books) {
            book.display();
        }
    }
}

public class Main {
    public static void main(String[] args) {
        List<Book> books = Arrays.asList(new Book("Head First Design Patterns"), new Book("Effective Java"));
        Library library = new Library(books);
        library.showBooks();
    }
}

3. Association (A General Relationship)

Definition:

Association is a general term for any relationship between two independent classes without ownership.

Example:

A Student and Teacher have an association.

class Student {
    private String name;
    
    Student(String name) {
        this.name = name;
    }
    
    void display() {
        System.out.println("Student: " + name);
    }
}

class Teacher {
    private String subject;
    
    Teacher(String subject) {
        this.subject = subject;
    }
    
    void teach(Student student) {
        System.out.println("Teacher teaching: " + subject);
        student.display();
    }
}

public class Main {
    public static void main(String[] args) {
        Student student = new Student("Alice");
        Teacher teacher = new Teacher("Math");
        
        teacher.teach(student);
    }
}

4. Multiple Inheritance (Interface-Based)

Definition:

Java does not support multiple inheritance with classes but allows it using interfaces.

Example:

interface Flyable {
    void fly();
}

interface Swimmable {
    void swim();
}

class Duck implements Flyable, Swimmable {
    public void fly() {
        System.out.println("Duck can fly");
    }
    
    public void swim() {
        System.out.println("Duck can swim");
    }
}

public class Main {
    public static void main(String[] args) {
        Duck duck = new Duck();
        duck.fly();
        duck.swim();
    }
}

5. Multilevel Inheritance

Definition:

Multilevel inheritance forms a chain of inheritance.

Example:

class Animal {
    void eat() {
        System.out.println("Animal eats");
    }
}

class Mammal extends Animal {
    void walk() {
        System.out.println("Mammal walks");
    }
}

class Dog extends Mammal {
    void bark() {
        System.out.println("Dog barks");
    }
}

public class Main {
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.eat();
        dog.walk();
        dog.bark();
    }
}

Comparison Table

Concept Definition Example
Is-A (Inheritance) Class is a type of another class Dog extends Animal
Has-A (Composition) Class contains another class Car has an Engine
Aggregation Class contains another class with weak dependency Library has Books
Association General relationship without ownership Student and Teacher
Multiple Inheritance A class implements multiple interfaces Duck implements Flyable, Swimmable
Multilevel Inheritance A class extends another, forming a chain Dog extends Mammal extends Animal

Final Thoughts

Understanding these concepts is crucial for designing scalable, maintainable software. Applying these principles correctly will make you a better software architect.

What are your thoughts? Do you prefer Is-A or Has-A in your projects? Let me know in the comments!