Inheritance, Interfaces and Abstract Classes

Single class inheritance with multiple interfaces. Traits (Module 18) give multiple inheritance of behavior.

final classes and methods prevent extension and overriding. sealed restricts subclasses (Groovy 4).

abstract class Shape {
    String name
    abstract double area()
    String describe() { "$name with area ${area().round(2)}" }
}

class Circle extends Shape {
    double r
    double area() { Math.PI * r * r }
}

class Square extends Shape {
    double side
    @Override double area() { side * side }
    String describe() { "Square! " + super.describe() }
}

interface Drawable {
    void draw()
    default String info() { "drawable" }       // default methods (Java 8 style)
    static Drawable noop() { { -> } as Drawable }
}

class Canvas implements Drawable {
    void draw() { println "Drawing canvas" }
}

List<Shape> shapes = [new Circle(name: "c", r: 1), new Square(name: "s", side: 2)]
shapes.each { println it.describe() }
println shapes*.area().sum()

def d = { println "closure as interface" } as Drawable    // closure coercion to an interface
d.draw()
def multi = [draw: { println "map draw" }, info: { "map info" }] as Drawable   // map coercion