Skip to content

Kapitel 6: Klassen und objektorientierte Programmierung

🎯 Lernziele

In diesem Kapitel lernen Sie:

  • ✅ Klassen in TypeScript definieren
  • ✅ Konstruktoren verwenden
  • ✅ Zugriffsmodifikatoren (public, private, protected)
  • readonly Eigenschaften
  • ✅ Statische Eigenschaften und Methoden
  • ✅ Interfaces mit Klassen implementieren
  • ✅ Abstrakte Klassen

6.1 Klassendefinition

📖 Einfache Definition

Eine Klasse ist ein Bauplan für Objekte.

💻 Code-Beispiel

typescript
// Klasse definieren
class Person {
  name: string;
  age: number;

  // Konstruktor
  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }

  // Methode
  greet(): string {
    return `Hallo, ich bin ${this.name} und bin ${this.age} Jahre alt.`;
  }
}

// Klasse verwenden
const max = new Person("Max", 25);
console.log(max.greet());  // Ausgabe: Hallo, ich bin Max und bin 25 Jahre alt.

6.2 Kurzschreibweise für Konstruktoren

💻 Code-Beispiel

typescript
// ❌ Langatmig
class Person1 {
  name: string;
  age: number;

  constructor(name: string, age: number) {
    this.name = name;
    this.age = age;
  }
}

// ✅ Kurzschreibweise (Parameter Properties)
class Person2 {
  constructor(public name: string, public age: number) {}

  greet(): string {
    return `Hallo, ich bin ${this.name}!`;
  }
}

const maria = new Person2("Maria", 30);
console.log(maria.greet());  // Ausgabe: Hallo, ich bin Maria!

6.3 Zugriffsmodifikatoren

📖 Einfache Definition

ModifikatorBedeutungZugriff von außenZugriff von Unterklassen
publicÖffentlich
privatePrivat
protectedGeschützt

💻 Code-Beispiel

typescript
class Person {
  public name: string;      // Von überall zugreifbar
  private age: number;       // Nur innerhalb der Klasse
  protected email: string;    // Innerhalb der Klasse + Unterklassen

  constructor(name: string, age: number, email: string) {
    this.name = name;
    this.age = age;
    this.email = email;
  }

  // Öffentliche Methode
  public greet(): string {
    return `Hallo, ich bin ${this.name}.`;
  }

  // Private Methode
  private calculateBirthYear(): number {
    return new Date().getFullYear() - this.age;
  }

  // Öffentliche Methode, die private Methode verwendet
  public getInfo(): string {
    const birthYear = this.calculateBirthYear();
    return `${this.greet()} Ich wurde im Jahr ${birthYear} geboren.`;
  }
}

const person = new Person("Max", 25, "max@example.com");

console.log(person.name);           // ✅ Erlaubt
console.log(person.greet());       // ✅ Erlaubt
console.log(person.getInfo());      // ✅ Erlaubt

console.log(person.age);           // ❌ Fehler: Property 'age' is private
console.log(person.email);         // ❌ Fehler: Property 'email' is protected
person.calculateBirthYear();       // ❌ Fehler: Methode is private

6.4 readonly Eigenschaften

📖 Einfache Definition

readonly Eigenschaften können nach der Initialisierung nicht mehr geändert werden.

💻 Code-Beispiel

typescript
class Person {
  public readonly id: number;  // Kann nur einmal zugewiesen werden
  public name: string;

  constructor(id: number, name: string) {
    this.id = id;
    this.name = name;
  }
}

const person = new Person(1, "Max");

console.log(person.id);    // ✅ Ausgabe: 1
person.name = "Maria";    // ✅ Erlaubt
person.id = 2;           // ❌ Fehler: Cannot assign to 'id' because it is a read-only property

6.5 Statische Eigenschaften (static)

📖 Einfache Definition

Statische Eigenschaften und Methoden gehören zur Klasse, nicht zu Instanzen.

💻 Code-Beispiel

typescript
class MathUtils {
  // Statische Eigenschaft
  static PI: number = 3.14159;

  // Statische Methode
  static add(a: number, b: number): number {
    return a + b;
  }

  static multiply(a: number, b: number): number {
    return a * b;
  }
}

// Zugriff ohne Instanziierung
console.log(MathUtils.PI);           // Ausgabe: 3.14159
console.log(MathUtils.add(5, 3));   // Ausgabe: 8
console.log(MathUtils.multiply(5, 3)); // Ausgabe: 15

// ❌ Fehler: Statische Eigenschaften sind nicht auf Instanzen verfügbar
const utils = new MathUtils();
console.log(utils.PI);  // Fehler!

6.6 Klasse implementiert Interface (implements)

📖 Einfache Definition

Eine Klasse kann ein oder mehrere Interfaces implementieren.

💻 Code-Beispiel

typescript
// Interface definieren
interface Animal {
  name: string;
  speak(): void;
}

// Klasse implementiert Interface
class Dog implements Animal {
  name: string;

  constructor(name: string) {
    this.name = name;
  }

  speak(): void {
    console.log(`${this.name} bellt: Wuff!`);
  }
}

class Cat implements Animal {
  name: string;

  constructor(name: string) {
    this.name = name;
  }

  speak(): void {
    console.log(`${this.name} miaut: Miau!`);
  }
}

// Verwendung
const dog: Animal = new Dog("Bello");
const cat: Animal = new Cat("Mizi");

dog.speak();  // Ausgabe: Bello bellt: Wuff!
cat.speak();  // Ausgabe: Mizi miaut: Miau!

6.7 Vererbung (extends)

📖 Einfache Definition

Eine Klasse kann von einer anderen Klasse erben.

💻 Code-Beispiel

typescript
// Basisklasse
class Animal {
  constructor(public name: string) {}

  move(distance: number = 0): void {
    console.log(`${this.name} bewegt sich um ${distance}m.`);
  }
}

// Abgeleitete Klasse
class Dog extends Animal {
  constructor(name: string) {
    super(name);  // Ruft den Konstruktor der Basisklasse auf
  }

  bark(): void {
    console.log(`${this.name} bellt: Wuff!`);
  }
}

// Verwendung
const dog = new Dog("Bello");
dog.move(10);   // Ausgabe: Bello bewegt sich um 10m.
dog.bark();     // Ausgabe: Bello bellt: Wuff!

6.8 Abstrakte Klassen (abstract)

📖 Einfache Definition

Abstrakte Klassen können nicht instanziiert werden. Sie dienen als Bauplan für andere Klassen.

💻 Code-Beispiel

typescript
// Abstrakte Klasse
abstract class Animal {
  constructor(public name: string) {}

  // Abstrakte Methode (muss in Unterklassen implementiert werden)
  abstract speak(): void;

  // Normale Methode
  move(): void {
    console.log(`${this.name} bewegt sich.`);
  }
}

// Konkrete Klasse
class Dog extends Animal {
  speak(): void {
    console.log(`${this.name} bellt: Wuff!`);
  }
}

class Cat extends Animal {
  speak(): void {
    console.log(`${this.name} miaut: Miau!`);
  }
}

// Verwendung
// const animal = new Animal("Tier");  // ❌ Fehler: Cannot create an instance of an abstract class

const dog: Animal = new Dog("Bello");
const cat: Animal = new Cat("Mizi");

dog.move();    // Ausgabe: Bello bewegt sich.
dog.speak();   // Ausgabe: Bello bellt: Wuff!

cat.move();     // Ausgabe: Mizi bewegt sich.
cat.speak();    // Ausgabe: Mizi miaut: Miau!

6.9 Praxis: TypeScript objektorientierte Fallstudie

💻 Vollständiges Beispiel

typescript
// Interface
interface CanFly {
  fly(): void;
}

// Abstrakte Klasse
abstract class Vehicle {
  constructor(public name: string, public speed: number) {}

  abstract move(): void;

  getInfo(): string {
    return `${this.name} bewegt sich mit ${this.speed} km/h.`;
  }
}

// Konkrete Klasse 1
class Car extends Vehicle {
  move(): void {
    console.log(`${this.name} fährt auf der Straße.`);
  }
}

// Konkrete Klasse 2 (implementiert zusätzliches Interface)
class Plane extends Vehicle implements CanFly {
  move(): void {
    console.log(`${this.name} fliegt durch die Luft.`);
  }

  fly(): void {
    console.log(`${this.name} hebt ab!`);
  }
}

// Verwendung
const car: Vehicle = new Car("Auto", 120);
const plane: Vehicle & CanFly = new Plane("Flugzeug", 800);

console.log(car.getInfo());  // Ausgabe: Auto bewegt sich mit 120 km/h.
car.move();                  // Ausgabe: Auto fährt auf der Straße.

console.log(plane.getInfo());  // Ausgabe: Flugzeug bewegt sich mit 800 km/h.
plane.move();                  // Ausgabe: Flugzeug fliegt durch die Luft.
plane.fly();                   // Ausgabe: Flugzeug hebt ab!

📝 Zusammenfassung

In diesem Kapitel haben Sie gelernt:

  • Klassen definieren mit class
  • Konstruktoren mit constructor
  • Zugriffsmodifikatoren: public, private, protected
  • readonly Eigenschaften
  • Statische Eigenschaften und Methoden (static)
  • Interfaces implementieren (implements)
  • Vererbung (extends)
  • Abstrakte Klassen (abstract)

🎯 Nächstes Kapitel

Im Kapitel 7 lernen wir Generics (Generische Typen) – ein fortgeschrittenes Konzept in TypeScript!

👉 Weiter zu Kapitel 7: Generics


❓ Häufig gestellte Fragen

F: Wann sollte ich private verwenden?

A: Wenn eine Eigenschaft oder Methode nur innerhalb der Klasse verwendet werden soll (Kapselung).

F: Was ist der Unterschied zwischen private und protected?

A:

  • private: Zugriff nur innerhalb der eigenen Klasse
  • protected: Zugriff innerhalb der eigenen Klasse und aller Unterklassen

F: Wann sollte ich abstrakte Klassen verwenden?

A: Wenn Sie einen Bauplan für mehrere verwandte Klassen erstellen möchten, aber die Basisklasse selbst nicht instanziiert werden soll.


🎉 Herzlichen Glückwunsch! Sie haben Kapitel 6 abgeschlossen!

Frei für alle Anfänger