Inheritance is a fundamental concept in object-oriented programming (OOP) that allows a class to inherit properties and methods from another class. This promotes code reuse and establishes a natural hierarchy between classes.

Key Concepts

  1. Base Class (Parent Class): The class whose properties and methods are inherited.
  2. Derived Class (Child Class): The class that inherits from the base class.
  3. extends Keyword: Used to indicate that a class is inheriting from another class.

Why Use Inheritance?

  • Code Reusability: Common functionality can be written once in the base class and reused in derived classes.
  • Hierarchical Classification: Establishes a natural hierarchy between classes, making the code more organized and understandable.
  • Polymorphism: Allows objects to be treated as instances of their parent class, enabling flexible and dynamic code.

Example: Basic Inheritance

Let's start with a simple example to illustrate inheritance in Groovy.

Base Class: Animal

class Animal {
    String name

    void eat() {
        println("${name} is eating.")
    }
}

Derived Class: Dog

class Dog extends Animal {
    void bark() {
        println("${name} is barking.")
    }
}

Using the Classes

def dog = new Dog()
dog.name = "Buddy"
dog.eat()  // Output: Buddy is eating.
dog.bark() // Output: Buddy is barking.

Explanation

  • The Animal class has a property name and a method eat().
  • The Dog class extends Animal, inheriting its properties and methods.
  • The Dog class also has its own method bark().
  • An instance of Dog can access both the inherited eat() method and its own bark() method.

Overriding Methods

Derived classes can override methods from the base class to provide specific implementations.

Example: Overriding the eat Method

class Dog extends Animal {
    void eat() {
        println("${name} is eating dog food.")
    }

    void bark() {
        println("${name} is barking.")
    }
}

def dog = new Dog()
dog.name = "Buddy"
dog.eat()  // Output: Buddy is eating dog food.
dog.bark() // Output: Buddy is barking.

Explanation

  • The Dog class overrides the eat() method from the Animal class.
  • When eat() is called on a Dog instance, the overridden method is executed.

Practical Exercise

Task

  1. Create a base class Vehicle with properties make and model, and a method start().
  2. Create a derived class Car that extends Vehicle and adds a method drive().
  3. Create an instance of Car, set its properties, and call both start() and drive() methods.

Solution

class Vehicle {
    String make
    String model

    void start() {
        println("${make} ${model} is starting.")
    }
}

class Car extends Vehicle {
    void drive() {
        println("${make} ${model} is driving.")
    }
}

def car = new Car()
car.make = "Toyota"
car.model = "Corolla"
car.start()  // Output: Toyota Corolla is starting.
car.drive()  // Output: Toyota Corolla is driving.

Explanation

  • The Vehicle class has properties make and model, and a method start().
  • The Car class extends Vehicle and adds a method drive().
  • An instance of Car is created, its properties are set, and both start() and drive() methods are called.

Common Mistakes

  • Forgetting to Use extends: Ensure that the derived class uses the extends keyword to inherit from the base class.
  • Overriding Methods Incorrectly: When overriding methods, ensure the method signature matches exactly with the base class method.

Summary

In this section, we covered the concept of inheritance in Groovy, including:

  • The basics of inheritance and its benefits.
  • How to create base and derived classes.
  • Overriding methods in derived classes.
  • Practical examples and exercises to reinforce the concepts.

Next, we will explore Interfaces and Traits in Groovy, which provide additional ways to achieve polymorphism and code reuse.

© Copyright 2024. All rights reserved