diff --git a/yuliya/aufgaben.md b/yuliya/aufgaben.md new file mode 100644 index 0000000..6ad3d9b --- /dev/null +++ b/yuliya/aufgaben.md @@ -0,0 +1,179 @@ +# Aufgabe 1 + +### Aufgabenstellung: + + +Erstellen Sie eine Klasse Person, die eine Instanzvariable name vom Typ String und +eine Instanzvariable age vom Typ int hat. Implementieren Sie einen entsprechenden +Kostruktor, der die Instanzvariablen initialisiert. +Fügen Sie außerdem eine Methode introduce() hinzu, +die eine Vorstellung der Person auf der Konsole ausgibt. Erstellen Sie eine Instanz +der Klasse und rufen Sie die Methode introduce() auf. + +### Lösung +``` +class Person { + String name + int age + + Person(String name, int age) { + this.name = name + this.age = age + } + + def introduce() { + println("Hello, my name is ${name} and I am ${age} years old.") + } +} + +// Verwendung der Klasse Person +def person = new Person("Alice", 30) +person.introduce() +``` + +# Aufgabe 2 +### Aufgabenstellung: + +a) Erstelle eine Klasse Calculator, die Methoden für die Grundrechenoperationen + Addition, Subtraktion, Multiplikation und Division bereitstellt. Implementiere die + Methoden add(int a, int b), subtract(int a, int b), multiply(int a, int b) und + divide(int a, int b). Die Methoden sollen die beiden übergebenen Zahlen + entsprechend der Operation verarbeiten und das Ergebnis zurückgeben. + +b) Erweitere die Klasse um eine Methode performOperation(int a, int b, Closure + operation), die eine Closure als Parameter akzeptiert. Diese Closure soll eine + Berechnung mit den beiden Zahlen durchführen und das Ergebnis zurückgeben. Zeige, + wie man diese Methode verwendet, indem du verschiedene Closures übergibst. + +### Lösung +``` +class Calculator { + def add(int a, int b) { + return a + b + } + + def subtract(int a, int b) { + return a - b + } + + def multiply(int a, int b) { + return a * b + } + + def divide(int a, int b) { + if (b == 0) { + println("Error: Division by zero!") + return + } + return a / b + } + + def performOperation(int a, int b, Closure operation) { + return operation(a, b) + } +} + +// Verwendung der Klasse Calculator +def calc = new Calculator() + +// Grundrechenoperationen +println("Addition: ${calc.add(5, 3)}") +println("Subtraction: ${calc.subtract(10, 7)}") +println("Multiplication: ${calc.multiply(4, 6)}") +println("Division: ${calc.divide(12, 4)}") + +// Closures definieren +def addClosure = { int a, int b -> a + b } +def subtractClosure = { int a, int b -> a - b } +def multiplyClosure = { int a, int b -> a * b } +def divideClosure = { int a, int b -> + if (b == 0) { + println("Error: Division by zero!") + return + } + return a / b +} + +// Verwendung von performOperation mit Closures +println("Addition mit Closure: ${calc.performOperation(5, 3, addClosure)}") +println("Subtraction mit Closure: ${calc.performOperation(10, 7, subtractClosure)}") +println("Multiplication mit Closure: ${calc.performOperation(4, 6, multiplyClosure)}") +println("Division mit Closure: ${calc.performOperation(12, 4, divideClosure)}") +``` + +# Aufgabe 3 +### Aufgabenstellung +Erstellen Sie eine Klasse EmployeeManager, die die Verwaltung von Mitarbeitern +ermöglicht. Die Klasse soll folgende Funktionen bieten: + +1. Hinzufügen von Mitarbeitern mit Name und Gehalt. +2. Aktualisieren des Gehalts eines Mitarbeiters. +3. Entfernen eines Mitarbeiters. +4. Durchführen von Gehaltsanpassungen für alle Mitarbeiter basierend auf einer Closure, die eine Gehaltsanpassungslogik definiert. +5. Abrufen einer Liste von Mitarbeitern, die nach einem bestimmten Kriterium gefiltert wurden (basierend auf einer übergebenen Closure). + +``` +class Employee { + String name + double salary + + Employee(String name, double salary) { + this.name = name + this.salary = salary + } + + String toString() { + return "Name: ${name}, Salary: ${salary}" + } +} + +class EmployeeManager { + List employees = [] + + void addEmployee(String name, double salary) { + employees << new Employee(name, salary) + } + + void updateSalary(String name, double newSalary) { + employees.find { it.name == name }?.salary = newSalary + } + + void removeEmployee(String name) { + employees.removeAll { it.name == name } + } + + void adjustSalaries(Closure adjustmentLogic) { + employees.each { it.salary = adjustmentLogic(it.salary) } + } + + List filterEmployees(Closure criteria) { + return employees.findAll(criteria) + } +} + +// Beispielnutzung der Klasse EmployeeManager +def manager = new EmployeeManager() + +// Hinzufügen von Mitarbeitern +manager.addEmployee("Alice", 50000) +manager.addEmployee("Bob", 60000) +manager.addEmployee("Charlie", 55000) + +// Aktualisieren des Gehalts eines Mitarbeiters +manager.updateSalary("Alice", 52000) + +// Entfernen eines Mitarbeiters +manager.removeEmployee("Charlie") + +// Durchführen von Gehaltsanpassungen für alle Mitarbeiter +manager.adjustSalaries { salary -> salary * 1.1 } // 10% Gehaltserhöhung + +// Filtern von Mitarbeitern basierend auf einem Kriterium +def highEarners = manager.filterEmployees { it.salary > 55000 } + +println("Alle Mitarbeiter:") +manager.employees.each { println it } + +println("\nHigh Earners:") +highEarners.each { println it } +``` diff --git a/yuliya/groovy_code_screenshots/folie10_methode_ohne_klasse.png b/yuliya/groovy_code_screenshots/folie10_methode_ohne_klasse.png new file mode 100644 index 0000000..cec1c19 Binary files /dev/null and b/yuliya/groovy_code_screenshots/folie10_methode_ohne_klasse.png differ diff --git a/yuliya/groovy_code_screenshots/folie11_instanzmethoden.png b/yuliya/groovy_code_screenshots/folie11_instanzmethoden.png new file mode 100644 index 0000000..f1a160b Binary files /dev/null and b/yuliya/groovy_code_screenshots/folie11_instanzmethoden.png differ diff --git a/yuliya/groovy_code_screenshots/folie12_statische_methoden.png b/yuliya/groovy_code_screenshots/folie12_statische_methoden.png new file mode 100644 index 0000000..6e1646b Binary files /dev/null and b/yuliya/groovy_code_screenshots/folie12_statische_methoden.png differ diff --git a/yuliya/groovy_code_screenshots/folie13_dynamische_methoden.png b/yuliya/groovy_code_screenshots/folie13_dynamische_methoden.png new file mode 100644 index 0000000..950179c Binary files /dev/null and b/yuliya/groovy_code_screenshots/folie13_dynamische_methoden.png differ diff --git a/yuliya/groovy_code_screenshots/folie14_expando.png b/yuliya/groovy_code_screenshots/folie14_expando.png new file mode 100644 index 0000000..e3f1a7b Binary files /dev/null and b/yuliya/groovy_code_screenshots/folie14_expando.png differ diff --git a/yuliya/groovy_code_screenshots/folie15_defaultparameter.png b/yuliya/groovy_code_screenshots/folie15_defaultparameter.png new file mode 100644 index 0000000..2ce22d0 Binary files /dev/null and b/yuliya/groovy_code_screenshots/folie15_defaultparameter.png differ diff --git a/yuliya/groovy_code_screenshots/folie16_clusures.png b/yuliya/groovy_code_screenshots/folie16_clusures.png new file mode 100644 index 0000000..3e2538c Binary files /dev/null and b/yuliya/groovy_code_screenshots/folie16_clusures.png differ diff --git a/yuliya/groovy_code_screenshots/folie17_closure_referenzierung.png b/yuliya/groovy_code_screenshots/folie17_closure_referenzierung.png new file mode 100644 index 0000000..8a8b38f Binary files /dev/null and b/yuliya/groovy_code_screenshots/folie17_closure_referenzierung.png differ diff --git a/yuliya/groovy_code_screenshots/folie18_closure_parameter.png b/yuliya/groovy_code_screenshots/folie18_closure_parameter.png new file mode 100644 index 0000000..9128d87 Binary files /dev/null and b/yuliya/groovy_code_screenshots/folie18_closure_parameter.png differ diff --git a/yuliya/groovy_code_screenshots/folie19_aufruf_closure.png b/yuliya/groovy_code_screenshots/folie19_aufruf_closure.png new file mode 100644 index 0000000..a5b7867 Binary files /dev/null and b/yuliya/groovy_code_screenshots/folie19_aufruf_closure.png differ diff --git a/yuliya/groovy_code_screenshots/folie20_closures_maps.png b/yuliya/groovy_code_screenshots/folie20_closures_maps.png new file mode 100644 index 0000000..2ae1437 Binary files /dev/null and b/yuliya/groovy_code_screenshots/folie20_closures_maps.png differ diff --git a/yuliya/groovy_code_screenshots/folie21_methodenverkettung.png b/yuliya/groovy_code_screenshots/folie21_methodenverkettung.png new file mode 100644 index 0000000..9fe3032 Binary files /dev/null and b/yuliya/groovy_code_screenshots/folie21_methodenverkettung.png differ diff --git a/yuliya/groovy_code_screenshots/folie22_mixin.png b/yuliya/groovy_code_screenshots/folie22_mixin.png new file mode 100644 index 0000000..5706674 Binary files /dev/null and b/yuliya/groovy_code_screenshots/folie22_mixin.png differ diff --git a/yuliya/groovy_code_screenshots/folie2_def_klasse.png b/yuliya/groovy_code_screenshots/folie2_def_klasse.png new file mode 100644 index 0000000..bc67917 Binary files /dev/null and b/yuliya/groovy_code_screenshots/folie2_def_klasse.png differ diff --git a/yuliya/groovy_code_screenshots/folie3_konstruktoren.png b/yuliya/groovy_code_screenshots/folie3_konstruktoren.png new file mode 100644 index 0000000..26d3711 Binary files /dev/null and b/yuliya/groovy_code_screenshots/folie3_konstruktoren.png differ diff --git a/yuliya/groovy_code_screenshots/folie4_mapkonstruktor.png b/yuliya/groovy_code_screenshots/folie4_mapkonstruktor.png new file mode 100644 index 0000000..4e4ef21 Binary files /dev/null and b/yuliya/groovy_code_screenshots/folie4_mapkonstruktor.png differ diff --git a/yuliya/groovy_code_screenshots/folie5_konstruktorueberladung.png b/yuliya/groovy_code_screenshots/folie5_konstruktorueberladung.png new file mode 100644 index 0000000..c050666 Binary files /dev/null and b/yuliya/groovy_code_screenshots/folie5_konstruktorueberladung.png differ diff --git a/yuliya/groovy_code_screenshots/folie6_eigenschaften.png b/yuliya/groovy_code_screenshots/folie6_eigenschaften.png new file mode 100644 index 0000000..2c009ea Binary files /dev/null and b/yuliya/groovy_code_screenshots/folie6_eigenschaften.png differ diff --git a/yuliya/groovy_code_screenshots/folie7_getter_setter.png b/yuliya/groovy_code_screenshots/folie7_getter_setter.png new file mode 100644 index 0000000..579e1be Binary files /dev/null and b/yuliya/groovy_code_screenshots/folie7_getter_setter.png differ diff --git a/yuliya/groovy_code_screenshots/folie9_def_methode.png b/yuliya/groovy_code_screenshots/folie9_def_methode.png new file mode 100644 index 0000000..dfdcce7 Binary files /dev/null and b/yuliya/groovy_code_screenshots/folie9_def_methode.png differ diff --git a/yuliya/klassen&methoden.md b/yuliya/klassen&methoden.md new file mode 100644 index 0000000..f33ca55 --- /dev/null +++ b/yuliya/klassen&methoden.md @@ -0,0 +1,429 @@ +# Klassen + +### Definition einer Klasse + + +Klassen in Groovy werden ähnlich wie in Java definiert, jedoch mit einigen +syntaktischen Erleichterungen: mit dem class-Schlüsselwort, ohne Semikolon + +Beispiel + ``` + class Person { + String name + int age +} + ``` + + +### Konstruktoren + +Groovy fügt automatisch einen Standardkonstruktor (="Default-Konstruktor") hinzu, wenn +keine Konstruktoren explizit definiert sind. Dieser Standardkonstruktor initialisiert alle +Eigenschaften der Klasse mit ihren Standardwerten. +Man kann auch benutzerdefinierte Konstruktoren definieren oder die beiden Konstruktorarten +auch gleichzeitig nutzen. Man spricht dabei von Konstruktorüberladung (auch wie in Java, +C++, C#...) + + ``` +class Person { + String name + int age + + //Default-Konstruktor + def person = new Person() + + //benutzerdefinierter Konstruktor + Person(String name, int age) { + this.name = name + this.age = age + } +} +``` + +``` +class Person { + String name + int age + + Person() { + // Standardkonstruktor + } + + Person(String name, int age) { + this.name = name + this.age = age + } +} + +def person1 = new Person() +println(person1.name) // Ausgabe: null +println(person1.age) // Ausgabe: 0 + +def person2 = new Person("Alice", 30) +println(person2.name) // Ausgabe: Alice +println(person2.age) // Ausgabe: 30 +``` + + +### Standardkonstruktor mit Map + +Groovy bietet eine spezielle Initialisierungsform mit einer Map an. Dieser Konstruktor +ermöglicht Objekte einfach und übersichtlich zu initialisieren, indem die Eigenschaften +des Objekts direkt in Form von Schlüssel-Wert-Paaren in der Map angegeben werden. +Groovy kümmert sich dann um die Zuordnung der Werte zu den entsprechenden Feldern der Klasse. + ``` + class Person { + String name + int age + + // Map-Konstruktor + Person(Map properties) { + properties.each { key, value -> this."$key" = value } + } +} + +Person person = new Person(name: 'John', age: 30) +println(person.name) // Ausgabe: John +println(person.age) // Ausgabe: 30 + ``` + + +### 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 +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") +} +} +``` + + + +# 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 Person { + String name + int age + + // Instanzmethode, um die Person vorzustellen + def introduce() { + println("Hello, my name is ${name} and I am ${age} years old.") + } +} + +Person person = new Person(name: 'Alice', age: 30) +person.introduce() +// Hello, my name is Alice and I am 30 years old. +``` + + +### 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 + +Groovy ermöglicht es, Methoden zur Laufzeit hinzuzufügen, was eine hohe Flexibilität bei der Gestaltung +von Klassen und deren Verhalten bietet. Diese Fähigkeit ist Teil der dynamischen Natur von Groovy und +wird durch die metaClass-Eigenschaft ermöglicht +``` +class DynamicExample {} + +// Hinzufügen einer Methode(=closure) zur Laufzeit +DynamicExample.metaClass.sayHello = { -> println "Hello, World!" } + +def example = new DynamicExample() +example.sayHello() +``` + +### Expando + +Expando ist eine spezielle Klasse 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-Parameter + +Methodenparameter können Standdardwerte haben (wie in Ruby). Diese werden eingesetzt, falls beim Aufruf keine Parameter +gesetzt werden. + +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() +// Sum is 13 +``` + + +### 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. +Closures enthalten Parameter, den Pfeil -> und den auszuführenden Code. Parameter sind +optional und werden, sofern angegeben, durch Kommas getrennt. + +1. Parameter + ``` +//closure takes one parameter - name - and prints it when invoked + +def greet = { String name -> println "Hello, $name!" } +greet.call("John") + ``` + +2. Referenzierung von Variablen und Rückgabewerte +Dieses Beispiel zeigt, wie Closures auf Variablen im auf Variablen im umgebenden Kontext +zugreifen und diese beibehalten können. Somit wird es Closures ermöglicht, Zustände +zwischen verschiedenen Aufrufen beizubehalten. + + + ``` +def createCounter() { + def count = 0 //lokale var + return { -> + count += 1 + return count + } +} + +//Ergebnis bzw. closure wird counter zugewiesen +def counter = createCounter() + +//counter hat zugriff auf count *innerhalb des Kontexts* +//in dem sie erstellt wurde + +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 + ``` + +### Wie ruft man eine Closure auf + +Eine Closure kann sowohl als eine reguläre Methode als auch mit call aufrufen werden + +``` +// Closure-Definition +def greet = { name -> + return "Hello, ${name}!" +} + +// Aufruf der Closure als reguläre Methode +println(greet("Alice")) // Ausgabe: Hello, Alice! + +// Aufruf der Closure mit call +println(greet.call("Bob")) // Ausgabe: Hello, Bob! +``` + + +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] + ``` + +Im Gegensatz zu einer regulären Groovy-Methode: + +- Wir können eine Closure als Argument an eine Methode übergeben +- Wir können eine Closure einer Variablen zuweisen und später ausführen, entweder als Methode oder mit call. +- Groovy bestimmt den Rückgabewert der Closures zur Laufzeit. +- Wir können Closures innerhalb einer Closure deklarieren und aufrufen. +- Closures geben immer einen Wert zurück + + +### Methodenverkettung + +Methodenverkettung ermöglicht,dass Methodenaufrufe direkt nacheinander aufeinanderfolgen können, indem das Objekt +selbst (normalerweise mit this) zurückgegeben wird. + Dies ermöglicht eine flüssige und verständliche Art, Methoden aufzurufen und zu kombinieren, insbesondere wenn diese + Methoden denselben oder ähnlichen Kontext haben. (wie in JS, ) + +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 + } +} + +// Erstellen einer neuen FluentPerson-Instanz und Methodenverkettung +def person = new FluentPerson() + .setName("Alice") + .setAge(30) + +println "Name: ${person.name}, Age: ${person.age}" // Ausgabe: Name: Alice, Age: 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") + ``` diff --git a/yuliya/klassen&methoden.pdf b/yuliya/klassen&methoden.pdf new file mode 100644 index 0000000..319ca37 Binary files /dev/null and b/yuliya/klassen&methoden.pdf differ