DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
View Events Video Library
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Migrate, Modernize and Build Java Web Apps on Azure: This live workshop will cover methods to enhance Java application development workflow.

Modern Digital Website Security: Prepare to face any form of malicious web activity and enable your sites to optimally serve your customers.

Kubernetes in the Enterprise: The latest expert insights on scaling, serverless, Kubernetes-powered AI, cluster security, FinOps, and more.

E-Commerce Development Essentials: Considering starting or working on an e-commerce business? Learn how to create a backend that scales.

Related

  • Simplify Java: Reducing Unnecessary Layers and Interfaces [Video]
  • A Complete Guide on iOS Accessibility Testing Tools
  • Transitioning From Groovy to Kotlin for Gradle Android Projects
  • The ABCs of Unity's Coroutines: From Basics to Implementation

Trending

  • Kubernetes vs. Amazon ECS: Container Orchestration Comparison
  • KubeAdmiral: Next-Generation Multi-Cluster Orchestration Engine Based on Kubernetes
  • The Efficiency of ELT Over ETL
  • Kubernetes Monitoring: Ensuring Performance and Stability in Containerized Environments
  1. DZone
  2. Coding
  3. Languages
  4. Groovy Goodness: Implement Interface and Abstract Methods Automatically

Groovy Goodness: Implement Interface and Abstract Methods Automatically

Let's take a look one of Groovy 2.5.0's numerous AST transformation annotations: @AutoImplement. Let's see its uses and how to implement it.

Hubert Klein Ikkink user avatar by
Hubert Klein Ikkink
·
Jun. 20, 18 · Tutorial
Like (3)
Save
Tweet
Share
10.4K Views

Join the DZone community and get the full member experience.

Join For Free

A lot of new AST transformation annotations were added in Groovy 2.5.0. One of them is the @AutoImplement annotation. If we apply this annotation to our class, dummy implementations for abstract methods in superclasses or methods in implemented interfaces are created. This can be useful just to have something in place and then gradually write real implementations for the abstract or interface methods. The transformation will not alter any method that is already implemented by custom code.

When we apply the @AutoImplement annotation, the default implementation for an abstract method from a superclass or method from a interface is simple. If the method has a return type, the default value of that return type is returned — for example, false for a boolean and null for an object type.

But the @AutoImplement annotation has some attributes we can use to change the default implementation. We can set the exception attribute and assign an exception type. The implementation of the methods is then to throw that exception when the method is invoked. With the optional message attribute, we can set the exception message. Finally, we can use the code attribute to define a Closure with statements that will be called as the implementation of abstract and interface methods.

In the following example, we have an interface Creator and create several classes that implement this interface and apply the @AutoImplement annotation with different attribute values:

import groovy.transform.AutoImplement
import static groovy.test.GroovyAssert.shouldFail

// Sample class with two simple properties.
@groovy.transform.Canonical
class Course {
    String name, location
}

// Interface with a single method to 
// create an object based on Map argument.
interface Creator<R> {
    R create(Map args)
}


// Use AutoImplement annotation to create object
// implementing the Creator interface. The compiled
// class will have an implementation for the create
// method. The return value is the default of the
// return type, in our case null.
@AutoImplement
class DefaultCourseCreator implements Creator<Course> { }

def defaultCreator = new DefaultCourseCreator()
assert defaultCreator.create(name: 'Groovy', location: 'Tilburg') == null


// When we use the AutoImplement annotation, only
// methods that are not implemented by ourselves
// will have an auto implementation.
@AutoImplement
class ImplCourseCreator implements Creator<Course> { 
    Course create(Map args) {
        new Course(args)
    }
}

def creator = new ImplCourseCreator()
assert creator.create(name: 'Groovy', location: 'Tilburg') == new Course(name: 'Groovy', location: 'Tilburg')


// Instead of returning the default value for the return type,
// we can throw an exception as default implementation.
// We can specify the type of exception and optionally the
// exception message.
@AutoImplement(exception = UnsupportedOperationException, 
               message = 'Not supported by NotSupportedCourseCreator')
class NotSupportedCourseCreator implements Creator<Course> { }

def creatorUnsupported = new NotSupportedCourseCreator()

def exception = shouldFail(UnsupportedOperationException) {
    creatorUnsupported.create(name: 'Groovy 101')
}
assert exception.message == 'Not supported by NotSupportedCourseCreator'


// We can use the code attribute of the AutoImplement annotation to
// specify a Closure. The Closure is used as implementation for the
// method from the interface.
// In this case we log a warning and return null as value. Notice
// we can access the log variable added by the Log annotation in 
// the Closure of the code attribute.
@groovy.util.logging.Log
@AutoImplement(code = { log.warning('Method needs implementation'); return null })
class ImplementCodeCourseCreator implements Creator<Course> { }

def creatorWarning = new ImplementCodeCourseCreator()
assert !creatorWarning.create(name: 'Groovy') // Prints log message "WARNING: Method needs implementation"


Written with Groovy 2.5.0.

Interface (computing) Groovy (programming language)

Published at DZone with permission of Hubert Klein Ikkink, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Simplify Java: Reducing Unnecessary Layers and Interfaces [Video]
  • A Complete Guide on iOS Accessibility Testing Tools
  • Transitioning From Groovy to Kotlin for Gradle Android Projects
  • The ABCs of Unity's Coroutines: From Basics to Implementation

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends: