Objektorientierte Programmierung

Geschätzte Lektüre: 10 Minuten 366 Ansichten

JavaScript ist eine multi-paradigmen Sprache, die auch objektorientierte Programmierung unterstützt, allerdings mit einigen einzigartigen Eigenschaften aufgrund ihres prototypenbasierten Ansatzes.

Grundkonzepte der OOP in JavaScript

Objekte

In JavaScript sind Objekte Sammlungen von Eigenschaften (key-value Paaren).

Beispiel:

const person = {
    vorname: "Max",
    nachname: "Mustermann",
    alter: 30,
    vorstellen: function() {
        console.log(`Hallo, ich bin ${this.vorname} ${this.nachname}.`);
    }
};

person.vorstellen(); // Ausgabe: "Hallo, ich bin Max Mustermann."

Konstruktorfunktionen

Vor ES6 wurden Objekte mit Konstruktorfunktionen erstellt.

Beispiel:

function Person(vorname, nachname, alter) {
    this.vorname = vorname;
    this.nachname = nachname;
    this.alter = alter;
    
    this.vorstellen = function() {
        console.log(`Hallo, ich bin ${this.vorname} ${this.nachname}.`);
    };
}

const max = new Person("Max", "Mustermann", 30);
max.vorstellen();

Klassen (seit ES6)

JavaScript hat eine Klassen-Syntax eingeführt, die syntaktischen Zucker über dem prototypenbasierten System darstellt.

Beispiel:

class Person {
    constructor(vorname, nachname, alter) {
        this.vorname = vorname;
        this.nachname = nachname;
        this.alter = alter;
    }
    
    vorstellen() {
        console.log(`Hallo, ich bin ${this.vorname} ${this.nachname}.`);
    }
}

const anna = new Person("Anna", "Musterfrau", 28);
anna.vorstellen();

Die vier Säulen der OOP in JavaScript

Kapselung (Encapsulation)

Das Verbergen von Implementierungsdetails und das Bereitstellen einer klar definierten Schnittstelle.

Beispiel mit privaten Feldern (seit ES2022):

class Bankkonto {
    #kontostand = 0; // Private field
    
    einzahlen(betrag) {
        if (betrag > 0) {
            this.#kontostand += betrag;
        }
    }
    
    get kontostand() {
        return this.#kontostand;
    }
}

const konto = new Bankkonto();
konto.einzahlen(100);
console.log(konto.kontostand); // 100
console.log(konto.#kontostand);
// Fehler: Private field kann nicht von außen zugegriffen werden

Vererbung (Inheritance)

JavaScript verwendet prototypische Vererbung, die mit der Klassen-Syntax vereinfacht wird.

Beispiel:

class Tier {
    constructor(name) {
        this.name = name;
    }
    
    essen() {
        console.log(`${this.name} isst.`);
    }
}

class Hund extends Tier {
    constructor(name, rasse) {
        super(name);
        this.rasse = rasse;
    }
    
    bellen() {
        console.log("Wuff!");
    }
}

const rex = new Hund("Rex", "Dackel");
rex.essen(); // "Rex isst."
rex.bellen(); // "Wuff!"

Polymorphismus

Die Fähigkeit, Methoden in abgeleiteten Klassen zu überschreiben.

Beispiel:

class Form {
    flaeche() {
        return 0;
    }
}

class Kreis extends Form {
    constructor(radius) {
        super();
        this.radius = radius;
    }
    
    flaeche() {
        return Math.PI * this.radius ** 2;
    }
}

class Rechteck extends Form {
    constructor(breite, hoehe) {
        super();
        this.breite = breite;
        this.hoehe = hoehe;
    }
    
    flaeche() {
        return this.breite * this.hoehe;
    }
}

const formen = [new Kreis(5), new Rechteck(4, 6)];

formen.forEach(form => {
    console.log(`Fläche: ${form.flaeche()}`);
});

Abstraktion

Das Konzept, komplexe Realität zu vereinfachen, indem nur die relevanten Eigenschaften modelliert werden.

Beispiel:

class ElektronischesGeraet {
    constructor(leistung) {
        if (new.target === ElektronischesGeraet) {
            throw new Error("Abstrakte Klasse kann nicht instanziiert werden");
        }
        this.leistung = leistung;
    }
    
    einschalten() {
        console.log("Gerät eingeschaltet");
    }
    
    // Abstrakte Methode
    betrieb() {
        throw new Error("Methode 'betrieb' muss implementiert werden");
    }
}

class Fernseher extends ElektronischesGeraet {
    constructor(leistung, groesse) {
        super(leistung);
        this.groesse = groesse;
    }
    
    betrieb() {
        console.log(`Zeigt Bild auf ${this.groesse} Zoll Bildschirm`);
    }
}

const tv = new Fernseher(150, 55);
tv.einschalten();
tv.betrieb();

Weitere fortgeschrittene Konzepte

Prototypen

JavaScript ist eine prototypbasierte Sprache. Jedes Objekt hat einen Prototyp, von dem es Eigenschaften erbt.

Beispiel:

const fahrzeug = {
    fahre: function() {
        console.log(`${this.typ} fährt.`);
    }
};

const auto = Object.create(fahrzeug);
auto.typ = "Auto";
auto.fahre(); // "Auto fährt."

Mixins

Eine Möglichkeit, Mehrfachvererbung zu simulieren.

Beispiel:

const kannFliegen = {
    fliege() {
        console.log(`${this.name} fliegt!`);
    }
};

const kannSchwimmen = {
    schwimme() {
        console.log(`${this.name} schwimmt!`);
    }
};

class Ente {
    constructor(name) {
        this.name = name;
    }
}

// Mixins einfügen
Object.assign(Ente.prototype, kannFliegen, kannSchwimmen);

const donald = new Ente("Donald");
donald.fliege();
donald.schwimme();

Statische Methoden und Eigenschaften

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

Beispiel:

class MatheHelfer {
    static pi = 3.14159;
    
    static kreisFlaeche(radius) {
        return this.pi * radius ** 2;
    }
}

console.log(MatheHelfer.kreisFlaeche(5)); // 78.53975
console.log(MatheHelfer.pi); // 3.14159

Getter und Setter

Spezielle Methoden, die wie Eigenschaften aufgerufen werden.

Beispiel:

class Rechteck {
    constructor(breite, hoehe) {
        this._breite = breite;
        this._hoehe = hoehe;
    }
    
    get flaeche() {
        return this._breite * this._hoehe;
    }
    
    set breite(wert) {
        if (wert > 0) {
            this._breite = wert;
        } else {
            console.log("Breite muss positiv sein");
        }
    }
}

const rechteck = new Rechteck(10, 5);
console.log(rechteck.flaeche); // 50 (getter wird aufgerufen)
rechteck.breite = 20; // setter wird aufgerufen
console.log(rechteck.flaeche); // 100

Design Patterns in JavaScript OOP

Factory Pattern

Erzeugt Objekte ohne den genauen Klassentyp angeben zu müssen.

Beispiel:

class Auto {
    fahre() {
        console.log("Auto fährt");
    }
}

class LKW {
    fahre() {
        console.log("LKW fährt");
    }
}

function fahrzeugFactory(typ) {
    switch(typ) {
        case "auto": return new Auto();
        case "lkw": return new LKW();
        default: throw new Error("Unbekannter Fahrzeugtyp");
    }
}

const meinAuto = fahrzeugFactory("auto");
meinAuto.fahre();

Singleton Pattern

Stellt sicher, dass eine Klasse nur eine Instanz hat.

Beispiel:

class Datenbank {
    constructor() {
        if (Datenbank.instance) {
            return Datenbank.instance;
        }
        
        this.verbindung = "DB-Verbindung hergestellt";
        Datenbank.instance = this;
    }
    
    query(sql) {
        console.log(`Ausführen: ${sql}`);
    }
}

const db1 = new Datenbank();
const db2 = new Datenbank();

console.log(db1 === db2); // true, es ist dieselbe Instanz

Unterschiede zu klassischer OOP (z.B. Java)

  1. Prototypen vs. Klassen: JavaScript verwendet prototypische Vererbung, auch wenn die Klassen-Syntax ähnlich aussieht.
  2. Dynamische Typisierung: Objekte können zur Laufzeit verändert werden.
  3. Keine echten Zugriffsmodifikatoren: Private Felder sind relativ neu (ES2022).
  4. Funktionen sind Objekte erster Klasse: Methoden sind einfach Eigenschaften, die Funktionen enthalten.

Best Practices für OOP in JavaScript

  1. Verwende class Syntax für bessere Lesbarkeit (außer bei sehr alten Browsern)
  2. Nutze Komposition über Vererbung, wo möglich
  3. Halte den Prototypenbaum flach
  4. Verwende private Felder (#feld) für echte Kapselung
  5. Vermeide die direkte Manipulation von __proto__ (verwende stattdessen Object.create() oder Object.setPrototypeOf())

JavaScripts OOP-System ist mächtig und flexibel, erfordert aber ein gutes Verständnis der prototypischen Natur der Sprache, um effektiv genutzt zu werden.

Dieses Dokument teilen

Objektorientierte Programmierung

Oder Link kopieren

INHALT

Abonnieren

×
Cancel