Dart Kurs Dokumentation wiederholen

Lektion 24 - Gesamtuebungen

Aufgaben zu allem, was du bisher gelernt hast

Diese Lektion ist dein Trainingsbereich. Du wiederholst Dart-Grundlagen, Flutter, OOP, Klassendiagramme, Operator Overloading und Entwicklerdokumentation. Jede Aufgabe soll aktiv gecodet werden.

0. Arbeitsweise fuer alle Aufgaben

Arbeite bei jeder Aufgabe in drei Schritten: Erst verstehen, dann planen, dann coden. Schreibe nicht sofort los, sondern formuliere zuerst kurz, was dein Programm tun soll.

Arbeitsweise:
  1. Aufgabe lesen
  2. Eingaben und Ausgaben notieren
  3. Loesungsweg kurz planen
  4. Dart- oder Flutter-Code schreiben
  5. Fehler pruefen
  6. Testfaelle ausprobieren
  7. Kurz dokumentieren, was die Loesung macht

1. Aufgabe: Code-Struktur lesen

Markiere gedanklich alle Klammern, Funktionen, Variablen und Rueckgabewerte. Danach erklaerst du jede Zeile in eigenen Worten.

  1. Erklaere, was void, main, String, int und return bedeuten.
  2. Zaehle alle runden, eckigen und geschweiften Klammern.
  3. Schreibe auf, wo eine Zuweisung stattfindet.
  4. Baue danach eine eigene Funktion formatUser.
String formatUser(String name, int points) {
  return '$name hat $points Punkte';
}

void main() {
  final result = formatUser('Mina', 42);
  print(result);
}

2. Aufgabe: Variablen, Typen und Null Safety

Schreibe ein kleines Programm, das einen Namen und ein Alter verarbeitet. Das Alter soll sicher geprueft werden.

  1. Lege String? fuer einen optionalen Namen an.
  2. Lege String fuer eine Alter-Eingabe an.
  3. Nutze int.tryParse.
  4. Wenn kein Name vorhanden ist, nutze 'Gast'.
  5. Gib aus, ob die Person volljaehrig ist.
void main() {
  String? name = null;
  String ageInput = '21';

  final displayName = name ?? 'Gast';
  final age = int.tryParse(ageInput);

  if (age == null) {
    print('Alter ist ungueltig.');
    return;
  }

  final status = age >= 18 ? 'volljaehrig' : 'nicht volljaehrig';
  print('$displayName ist $status.');
}

3. Aufgabe: Mutable und Immutable

Vergleiche eine mutable Liste mit einer immutable Arbeitsweise. Schreibe beide Varianten und erklaere den Unterschied.

  1. Erstelle eine final List<String> und fuege ein Element hinzu.
  2. Erstelle danach eine neue Liste mit dem Spread-Operator.
  3. Erklaere, warum final nicht automatisch die Liste selbst schuetzt.
  4. Baue eine immutable Klasse Todo mit copyWith.
class Todo {
  final String title;
  final bool isDone;

  const Todo({
    required this.title,
    required this.isDone,
  });

  Todo copyWith({
    String? title,
    bool? isDone,
  }) {
    return Todo(
      title: title ?? this.title,
      isDone: isDone ?? this.isDone,
    );
  }
}

4. Aufgabe: Entscheidungen in Dart

Plane zuerst kurz den Ablauf, danach schreibst du Dart-Code. Thema: Punktebewertung in einem Lernsystem.

  1. Wenn Punkte unter 0 sind, ist die Eingabe ungueltig.
  2. Ab 50 Punkten ist die Aufgabe bestanden.
  3. Ab 90 Punkten gibt es die Bewertung "sehr gut".
  4. Schreibe erst eine kurze Planung, danach Dart-Code.
String evaluate(int points) {
  if (points < 0) {
    return 'ungueltig';
  }

  if (points >= 90) {
    return 'sehr gut';
  }

  if (points >= 50) {
    return 'bestanden';
  }

  return 'nicht bestanden';
}

5. Aufgabe: Ternaerer Operator

Schreibe kurze Entscheidungen mit dem ternaeren Operator. Nutze ihn aber nur, wenn die Entscheidung gut lesbar bleibt.

  1. Erstelle String level aus Punkten.
  2. Erstelle bool hasPassed.
  3. Erstelle einen Ausgabetext mit String-Interpolation.
void main() {
  final points = 72;
  final hasPassed = points >= 50;
  final level = points >= 90 ? 'Profi' : 'Training';

  print('Status: ${hasPassed ? 'bestanden' : 'nicht bestanden'}');
  print('Level: $level');
}

6. Aufgabe: Methoden

Schreibe mehrere Methoden und achte auf klare Namen, Parameter und Rueckgabewerte.

  1. isAdult(int age) gibt bool zurueck.
  2. calculateTotal(int points, int bonus) gibt int zurueck.
  3. formatResult(String name, int points) gibt String zurueck.
  4. Schreibe zu jeder Methode vorher kurz Zweck, Eingabe und Ausgabe auf.
bool isAdult(int age) {
  return age >= 18;
}

int calculateTotal(int points, int bonus) {
  return points + bonus;
}

String formatResult(String name, int points) {
  return '$name erreicht $points Punkte.';
}

7. Aufgabe: Klassen, Attribute, Getter und Setter

Baue eine Klasse LearningUser. Sie soll Daten speichern und kontrolliert veraendern.

  1. Attribute: name, _points.
  2. Getter: points und hasPassed.
  3. Methode: addPoints.
  4. Negative Punkte sollen ignoriert werden.
class LearningUser {
  final String name;
  int _points;

  LearningUser(this.name, this._points);

  int get points => _points;
  bool get hasPassed => _points >= 50;

  void addPoints(int value) {
    if (value <= 0) {
      return;
    }

    _points += value;
  }
}

8. Aufgabe: Named Constructors und Enums

Erstelle Aufgaben mit Status. Nutze ein Enum und mehrere Konstruktoren.

  1. Enum TaskStatus mit open, done, blocked.
  2. Klasse LearningTask mit title, points, status.
  3. Named Constructor LearningTask.quick.
  4. Methode statusLabel().
enum TaskStatus {
  open,
  done,
  blocked,
}

class LearningTask {
  final String title;
  final int points;
  final TaskStatus status;

  const LearningTask(this.title, this.points, this.status);

  const LearningTask.quick(String title)
      : this(title, 5, TaskStatus.open);
}

9. Aufgabe: Komposition und Aggregation

Baue ein kleines Kursmodell. Ein Kurs hat mehrere Lektionen. Eine Lektion hat mehrere Aufgaben.

  1. Klasse Course mit Liste von Lesson.
  2. Klasse Lesson mit Liste von LearningTask.
  3. Methode totalTasks().
  4. Methode totalPoints().
class Course {
  final String title;
  final List<Lesson> lessons;

  const Course(this.title, this.lessons);

  int totalTasks() {
    return lessons.fold(0, (sum, lesson) => sum + lesson.tasks.length);
  }
}

10. Aufgabe: Vererbung

Erstelle eine Oberklasse und zwei Unterklassen. Ueberschreibe Methoden bewusst mit @override.

  1. Oberklasse Person mit name.
  2. Unterklasse Student mit course.
  3. Unterklasse Teacher mit subject.
  4. Alle Klassen haben introduce().
class Person {
  final String name;

  const Person(this.name);

  void introduce() {
    print('Ich bin $name.');
  }
}

class Student extends Person {
  final String course;

  const Student(String name, this.course) : super(name);

  @override
  void introduce() {
    print('Ich bin $name und lerne $course.');
  }
}

11. Aufgabe: Klassendiagramm

Zeichne zuerst ein Klassendiagramm in Textform und schreibe danach passenden Dart-Code.

  1. Plane Course, Lesson, LearningTask, User.
  2. Notiere Attribute und Methoden.
  3. Markiere Beziehungen mit 1, * und extends.
  4. Schreibe eine Klasse aus dem Diagramm als Dart-Code.
Course 1 -------- * Lesson
Lesson 1 -------- * LearningTask
User * -------- * Course

Course
  - title: String
  - lessons: List<Lesson>
  + totalTasks(): int

12. Aufgabe: Operator Overloading

Erstelle eine Klasse Score, mit der man Punkte addieren, vergleichen und lesbar ausgeben kann.

  1. Attribut value ist final.
  2. Ueberlade +.
  3. Ueberlade == und hashCode.
  4. Ueberschreibe toString().
class Score {
  final int value;

  const Score(this.value);

  Score operator +(Score other) {
    return Score(value + other.value);
  }

  @override
  String toString() {
    return '$value Punkte';
  }
}

13. Aufgabe: Flutter Counter erweitern

Plane und baue eine Counter-App mit mehreren Buttons. Notiere zuerst kurz, welche Button-Aktion welchen State aendert.

  1. Buttons fuer +1, -1, +2, -2.
  2. Button fuer Verdoppeln.
  3. Button fuer Halbieren.
  4. Lagere Button-Widget aus.
  5. Uebergib Parameter an das Button-Widget.
void changeCounter(int value) {
  setState(() {
    counter += value;
  });
}

void doubleCounter() {
  setState(() {
    counter *= 2;
  });
}

14. Aufgabe: Flutter Listen

Baue aus einer Liste sichtbare Widgets. Starte mit Column, danach mit ListView.builder.

  1. Erstelle eine Liste mit Aufgaben.
  2. Zeige jede Aufgabe als Text.
  3. Nutze danach ListView.builder.
  4. Fuege eine leere Liste als Sonderfall hinzu.
final tasks = ['Dart wiederholen', 'Flutter bauen'];

ListView.builder(
  itemCount: tasks.length,
  itemBuilder: (context, index) {
    return Text(tasks[index]);
  },
)

15. Aufgabe: Kompilierung und Commands

Schreibe eine Build-Checkliste fuer ein Flutter-Projekt und erklaere jeden Command.

  1. Was macht flutter pub get?
  2. Was macht flutter analyze?
  3. Wann nutzt du flutter run?
  4. Wann nutzt du flutter build web?
  5. Was ist der Unterschied zwischen Debug und Release?
Build-Plan:
  flutter pub get
  flutter analyze
  flutter test
  flutter build web

Wenn ein Schritt fehlschlaegt:
  Fehler lesen
  Ursache beheben
  Schritt erneut ausfuehren

16. Aufgabe: Entwicklerdokumentation

Dokumentiere dein Mini-Projekt so, dass eine andere Person es starten und verstehen kann.

  1. Schreibe eine Kurzbeschreibung.
  2. Notiere Start-Commands.
  3. Erklaere die wichtigsten Dateien.
  4. Dokumentiere eine Klasse mit DartDoc.
  5. Liste bekannte Grenzen auf.
# Mini-Lernprojekt

## Starten
[bash]
flutter pub get
flutter run
[/bash]

## Wichtige Dateien
- lib/main.dart
- lib/models/learning_task.dart
- lib/widgets/task_card.dart

17. Abschlussprojekt: Coding-Lernsystem Mini

Baue als Abschluss ein kleines Konsolenprogramm oder Flutter-Konzept fuer ein Coding-Lernsystem.

  1. Es gibt Kurse, Lektionen und Aufgaben.
  2. Aufgaben haben Punkte und Status.
  3. User sammeln Punkte.
  4. Nutze mindestens eine Klasse mit copyWith.
  5. Nutze mindestens ein Enum.
  6. Schreibe Projektplanung, Klassendiagramm und README-Abschnitt.
Projektplan:

Klassen:
  Course
  Lesson
  LearningTask
  LearningUser

Enums:
  TaskStatus

Methoden:
  completeTask()
  totalPoints()
  addLesson()

Dokumentation:
  README
  Start-Commands
  Klassendiagramm
  bekannte Grenzen
Zur Kursuebersicht