Klassen
class Konto {
final String inhaber;
double _stand; // _ macht Member privat (pro Datei)
static int anzahl = 0;
Konto(this.inhaber, [this._stand = 0]) { // Kurzform: Parameter direkt in Felder
anzahl++;
}
Konto.leer(String inhaber) : this(inhaber, 0); // benannter Konstruktor
double get stand => _stand; // Getter
set stand(double wert) { // Setter mit Prüfung
if (wert < 0) throw ArgumentError('Stand darf nicht negativ sein');
_stand = wert;
}
void einzahlen(double betrag) {
if (betrag <= 0) throw ArgumentError.value(betrag, 'betrag', 'muss positiv sein');
_stand += betrag;
}
@override
String toString() => '$inhaber: ${_stand.toStringAsFixed(2)}';
}
void main() {
var k = Konto('Mia', 100);
k.einzahlen(50);
print(k);
print('${k.stand} ${Konto.anzahl}');
var leer = Konto.leer('Tom');
print(leer);
try {
k.einzahlen(-5);
} on ArgumentError catch (e) {
print('Fehler: ${e.message}');
}
k.stand = 10;
print(k.stand);
var kette = StringBuffer()..write('a')..write('b')..write('c'); // Kaskade ..
print(kette);
}Ausgabe
Mia: 150.00 150.0 1 Tom: 0.00 Fehler: muss positiv sein 10.0 abc
Vererbung, abstrakte Klassen, Interfaces
abstract class Tier {
final String name;
Tier(this.name);
String laut();
String vorstellen() => '$name sagt ${laut()}';
}
class Hund extends Tier {
Hund(super.name); // Dart 3: super-Parameter
@override
String laut() => 'Wuff';
}
class Katze extends Tier {
int leben = 9;
Katze(super.name);
@override
String laut() => 'Miau';
@override
String vorstellen() => '${super.vorstellen()} ($leben Leben)';
}
abstract interface class Zahlbar { // Interface-Klasse
double betrag();
}
class Rechnung implements Zahlbar {
final double netto;
Rechnung(this.netto);
@override
double betrag() => netto * 1.19;
}
void main() {
List<Tier> tiere = [Hund('Rex'), Katze('Mimi')];
for (final t in tiere) { print(t.vorstellen()); }
print(tiere[0] is Hund);
if (tiere[1] case Katze k) { print('Katze mit ${k.leben} Leben'); }
Zahlbar z = Rechnung(100);
print(z.betrag().toStringAsFixed(2));
}Ausgabe
Rex sagt Wuff Mimi sagt Miau (9 Leben) true Katze mit 9 Leben 119.00
Mixins, Enums, Extensions
mixin Fliegen {
String fliegen() => 'fliegt';
}
mixin Schwimmen {
String schwimmen() => 'schwimmt';
}
class Ente with Fliegen, Schwimmen {}
enum Farbe {
rot('Rot', 0xFF0000),
gruen('Grün', 0x00FF00),
blau('Blau', 0x0000FF);
final String anzeige;
final int hex;
const Farbe(this.anzeige, this.hex);
String get code => '#${hex.toRadixString(16).padLeft(6, '0')}';
}
extension StringHelfer on String {
String get umgekehrt => split('').reversed.join();
bool get istPalindrom => this == umgekehrt;
}
extension IntHelfer on int {
bool get istPrim {
if (this < 2) return false;
for (var i = 2; i * i <= this; i++) { if (this % i == 0) return false; }
return true;
}
}
sealed class Form {} // geschlossene Hierarchie (Dart 3)
class Kreis extends Form { final double r; Kreis(this.r); }
class Quadrat extends Form { final double a; Quadrat(this.a); }
double flaeche(Form f) => switch (f) {
Kreis(r: var r) => 3.14159 * r * r,
Quadrat(a: var a) => a * a,
};
void main() {
var e = Ente();
print('${e.fliegen()} und ${e.schwimmen()}');
print('${Farbe.gruen.anzeige} ${Farbe.gruen.code} ${Farbe.values.length} ${Farbe.rot.name}');
print('${'Anna'.istPalindrom} ${'Dart'.umgekehrt} ${7.istPrim} ${[for (var i = 1; i < 20; i++) if (i.istPrim) i]}');
print('${flaeche(Kreis(1)).toStringAsFixed(2)} ${flaeche(Quadrat(3))}');
}Ausgabe
fliegt und schwimmt Grün #00ff00 3 rot false traD true [2, 3, 5, 7, 11, 13, 17, 19] 3.14 9.0
Generics
class Stapel<T> {
final List<T> _daten = [];
void push(T x) => _daten.add(x);
T? pop() => _daten.isEmpty ? null : _daten.removeLast();
int get groesse => _daten.length;
bool get istLeer => _daten.isEmpty;
}
T groesstes<T extends Comparable>(List<T> liste) {
var m = liste.first;
for (final x in liste) { if (x.compareTo(m) > 0) m = x; }
return m;
}
void main() {
var s = Stapel<int>();
s.push(1); s.push(2); s.push(3);
print('${s.pop()} ${s.pop()} ${s.groesse} ${s.istLeer}');
print('${groesstes([3, 9, 4])} ${groesstes(['kiwi', 'apfel'])}');
}Ausgabe
3 2 1 false 9 kiwi
Merke
- Klassen mit Konstruktorkurzform
Konto(this.name), benannten Konstruktoren, Gettern/Settern;_macht privat - Vererbung
extends, abstrakte Klassen,implementsfür Interfaces,withfür Mixins enummit Feldern,extensionfür Methoden an bestehenden Typen,sealedfür geschlossene Hierarchien- Kaskaden
.., Generics<T>
Aufgabe
Modelliere Formen als sealed class und berechne ihre Flächen mit einem switch-Ausdruck.