
- Groovy Tutorial
- Groovy - Home
- Groovy - Overview
- Groovy - Environment
- Groovy - Basic Syntax
- Groovy - Data Types
- Groovy - Variables
- Groovy - Optionals
- Groovy - Numbers
- Groovy - Strings
- Groovy - Ranges
- Groovy - Lists
- Groovy - Maps
- Groovy - Dates & Times
Groovy Operators
- Groovy - Operators
- Groovy - Arithmetic Operators
- Groovy - Assignment Operators
- Groovy - Relational Operators
- Groovy - Logical Operators
- Groovy - Bitwise Operators
- Groovy - Spaceship Operator
- Groovy - in Operator
- Groovy - Elvis Operator
- Groovy - Safe Navigation Operator
- Groovy Operator Precedence & Associativity
Control Statements
- Groovy - Decision Making
- Groovy - If Else Statement
- Groovy - Switch Statement
- Groovy - Loops
- Groovy - For Loop
- Groovy - For-in Loop
- Groovy - While Loop
- Groovy - Do While Loop
- Groovy - Break Statement
- Groovy - Continue Statement
Groovy File Handling
- Groovy - File I/O
- Java - Create a File
- Java - Write to File
- Java - Append to File
- Java - Read Files
- Java - Delete Files
- Java - File Properties
- Java - File Existence and Type
- Java - File Size
- Java - File Permissions
- Java - Directories
- Java - Listing Directories
- Java - Filtering Files/Directories
- Java - Deleting Directories
- Java - Renaming Files/Directories
Groovy Error & Exceptions
- Groovy - Exception Handling
- Groovy - try-catch Block
- Groovy - try-with-resources
- Groovy - Multi-catch Block
- Groovy - Nested try Block
- Groovy - Finally Block
- Groovy - throw Exception
- Groovy - Exception Propagation
- Groovy - Built-in Exceptions
- Groovy - Custom Exception
Groovy Multithreading
- groovy - Multithreading
- groovy - Thread Life Cycle
- groovy - Creating a Thread
- groovy - Starting a Thread
- groovy - Joining Threads
- groovy - Naming Thread
- groovy - Thread Scheduler
- groovy - Thread Pools
- groovy - Main Thread
- groovy - Thread Priority
- groovy - Daemon Threads
- groovy - Shutdown Hook
Groovy Synchronization
- groovy - Synchronization
- groovy - Block Synchronization
- groovy - Static Synchronization
- groovy - Inter-thread Communication
- groovy - Thread Deadlock
- groovy - Interrupting a Thread
- groovy - Thread Control
- groovy - Reentrant Monitor
- Groovy - Methods
- Groovy - Methods
- Groovy - Optional parenthesis
- Groovy - Named Arguments
- Groovy - Closures as Arguments
- Groovy - Method Overloading
- Groovy - Method Scope and Visibility
- Groovy - isCase Method
- Groovy - Implicit Return
- Groovy - Variable Arguments
- Groovy - Regular Expressions
- Groovy - Regular Expressions
- Groovy - Defining Regular Expressions
- Groovy - Matcher Object
- Groovy - Regex Tasks
- Groovy - XML
- Groovy - XML
- Groovy - Parsing XML
- Groovy - Creating XML
- Groovy - Modifying XML
- Groovy - Querying XML
- Groovy - Simplified Notation
- Groovy - Closure based Querying
- Groovy - Closure based Creation
- Groovy - JSON
- Groovy - JSON
- Groovy - Parsing JSON
- Groovy - Creating JSON using JsonOutput
- Groovy - Creating JSON using JsonBuilder
- Groovy - Modifying JSON
- Groovy - Error Handling
- Groovy - Handling JSON Arrays
- Groovy - JSON Array Operations
- Groovy - JSON Objects
- Groovy - JSON Object Operations
- Groovy - Generics
- Groovy - Generics
- Groovy - Declaring Generic Types
- Groovy - Bound Type Parameters
- Groovy - Wild Cards
- Groovy - Miscellaneous
- Groovy - Object Oriented
- Groovy - Closures
- Groovy - Annotations
- Groovy - JMX
- Groovy - DSLS
- Groovy - Database
- Groovy - Builders
- Groovy - Command Line
- Groovy - Unit Testing
- Groovy - Template Engines
- Groovy - Meta Object Programming
- Groovy Useful Resources
- Groovy - Quick Guide
- Groovy - Useful Resources
- Groovy - Discussion
Groovy - Implementing Multiple Traits
In Groovy, we can implement Traits in the same fashion as we can implement multiple interfaces but traits provides more flexibility and benefits.
Syntax
trait Trait1 {} trait Trait2 {} trait Trait3 {} class Multi implements Trait1, Trait2, Trait3 {}
Example - Implementing Multiple Traits
In this example, we're creating two traits to enable logging and save capability.
Create Traits
// in actual application, we can log the message in log file trait Loggable { void log(String message) { println "logging: ${message}" } } // in actual application, we can save data on disk/network and so trait Savable { void save(Object data) { println "Saving: ${data}" } }
Create a class implementing both Traits
Class MyReport implements Loggable, Savable { String title String content MyReport(String title, String content) { this.title = title this.content = content } void prepareReport() { // log is inherited from Loggable trait log("Preparing report: ${title}") println "Report '${title}' prepared successfully." } void saveReport() { log("Persisting report: ${title}") // save method is inherited from Savable trait save(this) // Save the report object itself } }
Use the Class
def salesReport = new MyReport("Daily Sales Details", "Total sales: $1000. Key products: TV, Mobile, Charger.") salesReport.prepareReport() salesReport.saveReport() // trait methods can be accessed directly as well salesReport.log("Report Analyzed") salesReport.save("Report Sent.")
Complete Example
Example.groovy
// in actual application, we can log the message in log file trait Loggable { void log(String message) { println "logging: ${message}" } } // in actual application, we can save data on disk/network and so trait Savable { void save(Object data) { println "Saving: ${data}" } } class MyReport implements Loggable, Savable { String title String content MyReport(String title, String content) { this.title = title this.content = content } void prepareReport() { // log is inherited from Loggable trait log("Preparing report: ${title}") println "Report '${title}' prepared successfully." } void saveReport() { log("Persisting report: ${title}") // save method is inherited from Savable trait save(this) // Save the report object itself } } def salesReport = new MyReport("Daily Sales Details", "Total sales: \$1000. Key products: TV, Mobile, Charger.") salesReport.prepareReport() salesReport.saveReport() // trait methods can be accessed directly as well salesReport.log("Report Analyzed") salesReport.save("Report Sent.")
Output
When we run the above program, we will get the following result.
logging: Preparing report: Daily Sales Details Report 'Daily Sales Details' prepared successfully. logging: Persisting report: Daily Sales Details Saving: MyReport@2ca923bb logging: Report Analyzed Saving: Report Sent.
Key Considerations
Conflict Resolution − In case, a class implementing the trait is having same method signature, the class method will take the precedence over the trait's one. Whereas if two traits are having same method signature than the rightmost trait takes the precedence. Another way to resolve conflict is to use trait name before trait method as trait-name.trait-method.
Composibility − By implementing functionalities in multiple traits and by implementing these traits, we can allow a class to have multiple functionalities.
Avoiding Diamond Problem of Multiple Inheritance − Diamond problem refers to having same method in two super classes and thus subclass has ambiguity in using such method if both super classes are extended. Traits solves this problem by providing automatic conflict resolution and method precedence.