Interfaces and abstract classes in Groovy

Interfaces and abstract classes are used in Groovy to define common behavior for classes that may be unrelated in terms of implementation but share a common contract or purpose. Here’s how to use interfaces and abstract classes in Groovy:

1. Interfaces: An interface is a contract that specifies a set of methods that a class must implement. In Groovy, you can define an interface using the `interface` keyword. Here’s an example:

interface Animal {
    void sayHello()
}

class Dog implements Animal {
    void sayHello() {
        println("Woof!")
    }
}

class Cat implements Animal {
    void sayHello() {
        println("Meow!")
    }
}

def dog = new Dog()
dog.sayHello()

def cat = new Cat()
cat.sayHello()

In this example, we define an interface called `Animal` with a method called `sayHello`, and two classes called `Dog` and `Cat` that implement the `Animal` interface and override the `sayHello` method to print a different message for each animal. We create instances of both classes and call the `sayHello` method on each instance, demonstrating the polymorphic behavior of the code.

2. Abstract classes: An abstract class is a class that cannot be instantiated directly but can be subclassed by other classes. Abstract classes can contain abstract methods, which are methods that have no implementation but must be implemented by any subclass of the abstract class. In Groovy, you can define anabstract class using the `abstract` keyword. Here’s an example:

abstract class Shape {
    abstract double getArea()
}

class Rectangle extends Shape {
    double width
    double height

    double getArea() {
        return width * height
    }
}

class Circle extends Shape {
    double radius

    double getArea() {
        return Math.PI * radius * radius
    }
}

def shapes = [new Rectangle(width: 5, height: 10), new Circle(radius: 5)]

for (shape in shapes) {
    println("The area of the shape is ${shape.getArea()}.")
}

In this example, we define an abstract class called `Shape` with an abstract method called `getArea`, and two classes called `Rectangle` and `Circle` that extend the `Shape` class and implement the `getArea` method to calculate the area of the shape. We create a list of shapes containing instances of both classes, and then loop over the list and call the `getArea` method on each shape, demonstrating the polymorphic behavior of the code.

Interfaces and abstract classes are important concepts in Groovy programming, and they allow you to define common behavior for classes that may be unrelated in implementation but share a common contract or purpose. By using interfaces and abstract classes, you can create code that is easier to read, maintain, and extend.