Groovy 2.3 introduced traits as a new language construct. We can apply traits when we write new classes in Groovy using the implements
keyword. But we can also apply traits dynamically at runtime. For example if we want to apply a trait to an already existing class and we cannot change the source code of that class.
To apply a single trait we can use the as
keyword. The original object is then coerced into the trait instance. In the following sample we define a new trait Name
with a couple of properties and a method. Also we have a User
class we want to apply this trait to. After we have applied the trait we can access the properties of the Name
trait and invoke the method getFullName
, actually we get a new object instance with the capabilities of the User
class and Name
trait:
trait Name { String salutation, firstName, lastName String getFullName() { [salutation, firstName, lastName].join(' ') } } class User { String username, password } def user = new User() as Name user.with { salutation = 'Mr.' firstName = 'Hubert' lastName = 'Klein Ikkink' username = 'mrhaki' password = '*****' } assert user.fullName == 'Mr. Hubert Klein Ikkink' assert user.username == 'mrhaki'
To apply multiple traits to an object we must use the method withTraits
on an object. We can use one or more traits as arguments to this method. In the following sample we apply the traits Id
, Version
and Active
with some properties and methods to an instance of the Person
class. The withTraits
methods return a new object instance which has all the properties and methods of the original class and the traits.
trait Id { Long id } trait Version { Long version = 0 } trait Active { Date from = new Date() Date to = null boolean isActive() { final Date now = new Date() from < now && (!to || to > now) } } class Person { String username } def person = new Person(username: 'mrhaki') def domainPerson = person.withTraits Id, Version, Active domainPerson.id = 1 assert domainPerson.username == 'mrhaki' assert domainPerson.id == 1 assert domainPerson.version == 0 assert domainPerson.active
Code written with Groovy 2.3.1.