## Klassen - Definition einer Klasse Klassen in Groovy werden ähnlich wie in Java definiert, jedoch mit einigen syntaktischen Erleichterungen Beispiel ``` class Person { String name int age } ``` - Eigenschaften Eigenschaften können direkt als Felder definiert werden. Groovy generiert automatisch Getter- und Setter-Methoden (wie in Ruby) Beispiel ``` Person person = new Person() person.name = "John" person.age = 30 person.age = 30 println person.name //John ``` Getter und Setter können aber auch manuell überschrieben werden Beispiel ``` class Fruits { private String fruitName private String fruitColor def setFruitName(String name) { fruitName = name } def getFruitName() { return "The fruitname is $fruitName" } def setFruitColor(String color) { fruitColor = color } def getFruitColor(){ return "The color is $fruitColor" } static void(args) { //Instanz erstellen Fruits apple = new Fruits() apple.setFruitName("apple") apple.setFruitColor("red") } } ``` - Konstruktoren Groovy fügt automatisch einen Standardkonstruktor hinzu. Man kann auch benutzerdefinierte Konstruktoren definieren. ``` class Person { String name int age Person(String name, int age) { this.name = name this.age = age } } ``` - Standardkonstruktor mit Map Groovy bietet eine spezielle Initialisierungsform mit einer Map an ``` Person person = new Person(name: 'John', age: 30) ``` ## Methoden - Definition einer Methode Methoden werden ähnlich wie in Java definiert, können aber optional einen Rückgabetyp haben ``` class Calculator { int add(int a, int b) { return a + b } } ``` In Groovy können Methoden direkt ohne Klasse und main-Methode definiert und aufgerufen werden. Beispiel 1 ``` def printHello() { println "Hello..." } printHello() def sum(int a, int b) { println "Sum is "+(a+b) } sum(5,2) //Hello... // 7 ``` - Instanzmethoden Methoden können Instanzmethoden sein und auf Instanzvariablen zugreifen. ``` class Method { static void main(args) { Method myFunc = new Method() myFunc.myMethod() } def myMethod() { println("I am inside my method") } } ``` - Statische Methoden ``` class MathUtils { // Definition einer statischen Methode static int add(int a, int b) { return a + b } static void main(String[] args) { // Aufruf der statischen Methode ohne Instanz der Klasse int result = MathUtils.add(5, 10) println("Sum is $result") // Ausgabe: Sum is 15 } } ``` - Dynamische Methoden Groovy erlaubt es, Methoden zur Laufzeit hinzuzufügen. In diesem Beispiel wird die Methode sayHello zur Klasse DynamicExample hinzugefügt, nachdem die Klasse bereits definiert wurde Beispiel ``` class DynamicExample {} // Hinzufügen einer Methode zur Laufzeit DynamicExample.metaClass.sayHello = { -> println "Hello, World!" } def example = new DynamicExample() example.sayHello() ``` - Expando Ist eine spezielle Klassen in Groovy, die ermöglicht Objekten zur Laufzeit dynamisch Methoden und Eigenschaften hinzuzufügen. Dadurch ist die vorherige Deklaration der Felder in der Klasse nicht nötig Beispiel ``` // Erstellen eines Expando-Objekts def expando = new Expando() // Hinzufügen einer Eigenschaft 'name' und Zuweisung des Wertes "Groovy" expando.name = "Groovy" // Hinzufügen einer Methode 'sayHello', die eine Nachricht ausgibt, die die Eigenschaft 'name' verwendet expando.sayHello = { -> println "Hello from $name" } // Aufrufen der Methode 'sayHello', was die Nachricht "Hello from Groovy" ausgibt expando.sayHello() // Ausgabe: Hello from Groovy ``` - Default-Parameterwerte Methodenparameter können Standdardwerte haben(wie in Ruby) Beispiel 1 ``` class Greeter { void greet(String name = "World") { println "Hello, $name!" } } ``` Ruft man die Methode ohne Parameter auf, werden die Default-Paramter eingesetzt Beispiel 2 ``` def sum(int a=10, int b=3) { println "Sum is "+(a+b) } sum() ``` - Closures Closures können auf Variablen aus ihrem umgebenden Gültigkeitsbereich zugreifen und diese „einfangen“. Dadurch können sie auf Werte zugreifen, die zum Zeitpunkt ihrer Erstellung existierten. 1. Parameter ``` def greet = { String name -> println "Hello, $name!" } greet.call("John") ``` 2. Referenzierung von Variablen und Rückgabewerte ``` def createCounter() { def count = 0 return { -> count += 1 return count } } def counter = createCounter() println(counter()) // Ausgabe: 1 println(counter()) // Ausgabe: 2 ``` 3. Übergabe als Parameter ``` def performOperation(int x, Closure operation) { return operation(x) } def closure = { y -> y * 2 } def result = performOperation(5, closure) println(result) // Ausgabe: 10 ``` Methoden können auch auf Maps und Listen angewendet werden, besonders nützlich mit Closures. ``` def myMap = [ 'subject': 'groovy', 'topic': 'closures'] println myMap.each { it } def myList = [1, 2, 3, 4, 5] println myList.find { item -> item == 3 } // 3 println myList.findAll { item -> item > 3 } // [4, 5] println myList.any { item -> item > 5 } // false println myList.every { item -> item > 3 } // false println myList.collect { item -> item * 2 } // [2, 4, 6, 8, 10] ``` - Methodenverkettung Durch das Rückgeben von this kann man Methodenaufrufe verketten. Beispiel ``` class FluentPerson { String name int age FluentPerson setName(String name) { this.name = name return this } FluentPerson setAge(int age) { this.age = age return this } } def person = new FluentPerson().setName("John").setAge(30) ``` - Mixin(Misching) Man kann Funktionalität zu Klassen hinzufügen, ohne Vererbung zu verwenden, indem man Mixins verwendet. Beispiel ``` class ExtraMethods { String shout(String str) { return str.toUpperCase() } } @Mixin(ExtraMethods) class MyClass {} def myObject = new MyClass() println myObject.shout("hello") ```