Fortgeschritten162025-01-15

TypeScript Classes - Objektorientierte Programmierung

Lerne Classes in TypeScript mit Access Modifiers, Constructors, Inheritance, Abstract Classes und mehr.

#typescript#classes#oop#inheritance

TypeScript Classes - Objektorientierte Programmierung

TypeScript erweitert JavaScript Classes um Access Modifiers, Abstract Classes und mehr.

Class Basics

Einfache Class

class Person {
  name: string
  age: number

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

  greet(): string {
    return `Hello, I'm ${this.name}`
  }
}

const person = new Person("Max", 25)
console.log(person.greet()) // "Hello, I'm Max"

Shorthand Constructor

TypeScript hat eine kürzere Syntax:

// Lange Version
class Person {
  name: string
  age: number

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

// Kurze Version - identisch!
class Person {
  constructor(
    public name: string,
    public age: number
  ) {}
}

Das public Keyword erstellt automatisch Properties!

Access Modifiers

TypeScript hat 3 Access Modifiers:

public (Standard)

Von überall zugänglich:

class Person {
  public name: string // public ist default

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

const person = new Person("Max")
console.log(person.name) // ✅ OK

private

Nur innerhalb der Class zugänglich:

class Person {
  private age: number

  constructor(age: number) {
    this.age = age
  }

  getAge(): number {
    return this.age // ✅ OK innerhalb der Class
  }
}

const person = new Person(25)
console.log(person.age) // ❌ Error: age is private
console.log(person.getAge()) // ✅ OK: 25

protected

Innerhalb der Class UND Subclasses:

class Person {
  protected name: string

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

class Employee extends Person {
  getEmployeeName(): string {
    return this.name // ✅ OK in Subclass
  }
}

const person = new Person("Max")
console.log(person.name) // ❌ Error: name is protected

Readonly Properties

Properties die nach Constructor nicht änderbar sind:

class Person {
  readonly id: number
  name: string

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

  changeName(newName: string) {
    this.name = newName // ✅ OK
    this.id = 999 // ❌ Error: readonly
  }
}

const person = new Person(1, "Max")
person.name = "Anna" // ✅ OK
person.id = 2 // ❌ Error: readonly

Getters und Setters

Computed Properties mit Validierung:

class Person {
  private _age: number = 0

  get age(): number {
    return this._age
  }

  set age(value: number) {
    if (value < 0 || value > 150) {
      throw new Error("Invalid age")
    }
    this._age = value
  }
}

const person = new Person()
person.age = 25 // Nutzt Setter
console.log(person.age) // Nutzt Getter: 25

person.age = -5 // ❌ Error: Invalid age

Best Practice: Private Property mit _ und public Getter/Setter

Static Members

Properties/Methoden auf der Class selbst:

class MathHelper {
  static PI: number = 3.14159

  static calculateCircleArea(radius: number): number {
    return this.PI * radius * radius
  }
}

// Ohne Instanz aufrufen
console.log(MathHelper.PI) // 3.14159
console.log(MathHelper.calculateCircleArea(5)) // 78.54

Nutzung:

class Counter {
  static count: number = 0

  constructor() {
    Counter.count++ // Zugriff auf static member
  }

  static getCount(): number {
    return Counter.count
  }
}

new Counter()
new Counter()
console.log(Counter.getCount()) // 2

Inheritance (Vererbung)

Classes können von anderen Classes erben:

class Animal {
  constructor(public name: string) {}

  move(distance: number): void {
    console.log(`${this.name} moved ${distance}m`)
  }
}

class Dog extends Animal {
  bark(): void {
    console.log("Woof! Woof!")
  }
}

const dog = new Dog("Buddy")
dog.move(10) // "Buddy moved 10m"
dog.bark() // "Woof! Woof!"

super() im Constructor

Subclass muss super() aufrufen:

class Animal {
  constructor(public name: string) {}
}

class Dog extends Animal {
  constructor(name: string, public breed: string) {
    super(name) // ✅ Muss ZUERST aufgerufen werden
    this.breed = breed
  }
}

const dog = new Dog("Buddy", "Golden Retriever")

Methoden überschreiben

class Animal {
  makeSound(): void {
    console.log("Some sound")
  }
}

class Dog extends Animal {
  makeSound(): void {
    console.log("Woof!")
  }
}

class Cat extends Animal {
  makeSound(): void {
    console.log("Meow!")
  }
}

const animals: Animal[] = [new Dog(), new Cat()]
animals.forEach(animal => animal.makeSound())
// "Woof!"
// "Meow!"

Abstract Classes

Classes die NICHT instanziiert werden können:

abstract class Shape {
  abstract getArea(): number // Muss implementiert werden

  printArea(): void {
    console.log(`Area: ${this.getArea()}`)
  }
}

class Circle extends Shape {
  constructor(public radius: number) {
    super()
  }

  getArea(): number {
    return Math.PI * this.radius ** 2
  }
}

class Rectangle extends Shape {
  constructor(
    public width: number,
    public height: number
  ) {
    super()
  }

  getArea(): number {
    return this.width * this.height
  }
}

const circle = new Circle(5)
circle.printArea() // "Area: 78.54"

const shape = new Shape() // ❌ Error: Cannot create instance of abstract class

Verwendung:

  • Base Classes mit gemeinsamer Logik
  • Enforced Methods in Subclasses
  • Polymorphismus

Implementing Interfaces

Classes können Interfaces implementieren:

interface Printable {
  print(): void
}

interface Saveable {
  save(): void
}

class Document implements Printable, Saveable {
  constructor(public title: string) {}

  print(): void {
    console.log(`Printing: ${this.title}`)
  }

  save(): void {
    console.log(`Saving: ${this.title}`)
  }
}

const doc = new Document("My Doc")
doc.print()
doc.save()

Interface vs Abstract Class:

| Feature | Interface | Abstract Class | |---------|-----------|----------------| | Implementierung | Nur Signatur | Kann Implementierung haben | | Multiple | ✅ Ja | ❌ Nein (nur single inheritance) | | Constructor | ❌ Nein | ✅ Ja | | Access Modifiers | ❌ Nein | ✅ Ja |

Parameter Properties

Shorthand für Properties im Constructor:

class Person {
  constructor(
    public name: string,
    private age: number,
    protected email: string,
    readonly id: number
  ) {}
}

// Identisch zu:
class Person {
  public name: string
  private age: number
  protected email: string
  readonly id: number

  constructor(name: string, age: number, email: string, id: number) {
    this.name = name
    this.age = age
    this.email = email
    this.id = id
  }
}
Vollständige Class mit allen Features
abstract class Employee {
  private static nextId: number = 1
  readonly id: number

  constructor(
    public name: string,
    protected salary: number
  ) {
    this.id = Employee.nextId++
  }

  abstract calculateBonus(): number

  get monthlySalary(): number {
    return this.salary / 12
  }

  set monthlySalary(value: number) {
    this.salary = value * 12
  }

  displayInfo(): void {
    console.log(`${this.name} (ID: ${this.id})`)
  }
}

class Developer extends Employee {
  constructor(
    name: string,
    salary: number,
    public programmingLanguage: string
  ) {
    super(name, salary)
  }

  calculateBonus(): number {
    return this.salary * 0.15
  }

  code(): void {
    console.log(`Coding in ${this.programmingLanguage}`)
  }
}

const dev = new Developer("Max", 60000, "TypeScript")
dev.displayInfo()
console.log(dev.calculateBonus())
dev.code()

📝 Quiz

Was ist der Unterschied zwischen private und protected?

Tipps & Tricks

Private Fields mit

ES2022 hat echte Private Fields:

class Person {
  #age: number // Echtes Private Field

  constructor(age: number) {
    this.#age = age
  }

  getAge() {
    return this.#age
  }
}

Unterschied zu TypeScript private:

  • private ist nur Compile-Time
  • # ist Runtime Private

Method Chaining

class Calculator {
  private value: number = 0

  add(n: number): this {
    this.value += n
    return this
  }

  multiply(n: number): this {
    this.value *= n
    return this
  }

  getResult(): number {
    return this.value
  }
}

const result = new Calculator()
  .add(5)
  .multiply(2)
  .add(3)
  .getResult() // 13

Generic Classes

class Box<T> {
  constructor(private value: T) {}

  getValue(): T {
    return this.value
  }

  setValue(value: T): void {
    this.value = value
  }
}

const numberBox = new Box(42)
const stringBox = new Box("Hello")

Häufige Fehler

Fehler 1: super() vergessen

FALSCH:

class Animal {
  constructor(public name: string) {}
}

class Dog extends Animal {
  constructor(name: string, breed: string) {
    this.breed = breed // ❌ Error: 'super' must be called first
  }
}

RICHTIG:

class Dog extends Animal {
  constructor(name: string, public breed: string) {
    super(name) // ✅ ZUERST super()
    this.breed = breed
  }
}

Fehler 2: this in Arrow Functions

PROBLEM:

class Button {
  text: string = "Click"

  handleClick = function() {
    console.log(this.text) // this kann undefined sein
  }
}

RICHTIG:

class Button {
  text: string = "Click"

  handleClick = () => {
    console.log(this.text) // this ist immer Button
  }
}

Fehler 3: Abstract Methoden ohne abstract keyword

FALSCH:

abstract class Shape {
  getArea(): number {
    return 0 // Dummy Implementierung
  }
}

RICHTIG:

abstract class Shape {
  abstract getArea(): number // Muss implementiert werden
}
🎯

Zusammenfassung

Du hast gelernt:

  • ✅ Classes mit Properties und Methoden
  • ✅ Access Modifiers: public, private, protected
  • ✅ Readonly Properties
  • ✅ Getters und Setters
  • ✅ Static Members
  • ✅ Inheritance mit extends
  • ✅ Abstract Classes
  • ✅ Interfaces implementieren

Key Takeaways:

  • Parameter Properties für kürzeren Code
  • Private für Encapsulation
  • Abstract Classes für gemeinsame Basis
  • Interface für Contracts
  • super() muss zuerst aufgerufen werden

Nächste Schritte

Als Nächstes lernst du:

  • Generics im Detail
  • Advanced Types
  • Decorators
  • TypeScript mit React

Viel Erfolg! 🚀

TypeScriptLektion 5 von 15
33% abgeschlossen
Lektion abgeschlossen!

Gut gemacht! 🎉

Du hast "TypeScript Classes - Objektorientierte Programmierung" abgeschlossen

Artikel bewerten

0.0 (0 Bewertungen)

Bitte einloggen um zu bewerten