Groovy Composition: Alternative to Inheritance
In Groovy, a Trait is a concept similar to Java's interface but more powerful and flexible. Traits can contain implementations of attributes and methods, and they can be combined by multiple classes or other Traits without the need for inheritance, thereby avoiding the multiple inheritance issues found in Java.
The following example demonstrates how to define and use Traits in Groovy:
trait Flyable {
void fly() {
println("I'm flying!")
}
}
trait Swimmable {
void swim() {
println("I'm swimming!")
}
}
class Bird implements Flyable {
String name
Bird(String name) {
this.name = name
}
void sayHello() {
println("Hello, I'm a bird, my name is ${name}.")
}
}
class Duck implements Flyable, Swimmable {
void sayHello() {
println("Hello, I'm a duck.")
}
}
def bird = new Bird("Eagle")
bird.sayHello() // Output: "Hello, I'm a bird, my name is Eagle."
bird.fly() // Output: "I'm flying!"
def duck = new Duck()
duck.sayHello() // Output: "Hello, I'm a duck."
duck.fly() // Output: "I'm flying!"
duck.swim() // Output: "I'm swimming!"
In the example above, we defined two Traits: Flyable and Swimmable, which implement the fly and swim methods respectively. Subsequently, we defined a Bird class and a Duck class, each implementing one or more Traits and defining their own methods. Finally, we instantiated objects of both classes and invoked their respective methods.
It is important to note that in Groovy, Traits support both inheritance and composition. Relationships between Traits can be defined using the extends and implements keywords. Attributes and methods within a Trait can be modified using keywords such as abstract, default, or static, making Traits more flexible and powerful.