Skip to content
IRC-Coding IRC-Coding
OOP Begriffe Attribute Nachrichten Methodenaufruf Persistenz Schnittstellen API

OOP Begriffe: Attribute, Nachrichten, Methodenaufruf, Persistenz & Schnittstellen

Wichtige OOP-Begriffe erklärt. Attribute (Eigenschaften), Nachrichten (Methodenaufruf), Persistenz (Datenhaltung), Schnittstellen (API) mit praktischen Beispielen.

S

schutzgeist

2 min read

OOP Begriffe: Attribute, Nachrichten, Methodenaufruf, Persistenz & Schnittstellen

Dieser Beitrag ist eine umfassende Erklärung der wichtigsten OOP-Begriffe – inklusive Attribute, Nachrichten, Methodenaufruf, Persistenz und Schnittstellen mit praktischen Beispielen.

In a Nutshell

OOP-Begriffe beschreiben die fundamentalen Konzepte objektorientierter Programmierung: Attribute als Eigenschaften, Nachrichten als Kommunikation, Persistenz als Datenhaltung und Schnittstellen als Verträge.

Kompakte Fachbeschreibung

Objektorientierte Programmierung (OOP) verwendet spezifische Begriffe zur Beschreibung von Konzepten und Strukturen.

Attribut (Attribute/Field/Property)

Ein Attribut ist eine Eigenschaft oder ein Zustand eines Objekts. Es beschreibt Daten, die ein Objekt enthält.

Eigenschaften:

  • Datentyp: Definiert Art der Daten (String, int, boolean, etc.)
  • Sichtbarkeit: public, private, protected, package
  • Wert: Aktueller Zustand der Eigenschaft
  • Lebensdauer: Existiert so lange wie das Objekt

Nachricht (Message/Methodenaufruf)

Eine Nachricht ist die Kommunikation zwischen Objekten. Sie fordert ein Objekt auf, eine bestimmte Aktion auszuführen.

Komponenten:

  • Empfänger: Objekt, das die Nachricht erhält
  • Selektor: Name der aufzurufenden Methode
  • Argumente: Parameter für die Methode
  • Rückgabewert: Ergebnis der Operation

Persistenz (Persistence)

Persistenz bezeichnet die Dauerhaftigkeit von Daten über die Programmlaufzeit hinaus.

Arten der Persistenz:

  • Dateisystem: Serialisierung in Dateien
  • Datenbanken: Relationale oder NoSQL-Datenbanken
  • Cloud-Speicher: Externe Speicherdienste
  • In-Memory: Temporäre Persistenz

Schnittstelle (Interface/API)

Eine Schnittstelle definiert einen Vertrag zwischen Komponenten und beschreibt, welche Operationen verfügbar sind.

Typen von Schnittstellen:

  • Programmierschnittstellen: Methoden-Signaturen
  • Web-APIs: HTTP-Endpunkte
  • Benutzerschnittstellen: GUI-Komponenten
  • Hardware-Schnittstellen: Gerätetreiber

Prüfungsrelevante Stichpunkte

  • Attribute: Eigenschaften/Daten von Objekten mit Sichtbarkeit
  • Nachrichten: Kommunikation zwischen Objekten via Methodenaufruf
  • Methodenaufruf: Ausführung von Operationen auf Objekten
  • Persistenz: Dauerhafte Datenspeicherung über Programmlaufzeit
  • Schnittstellen: Verträge zwischen Komponenten, definierte APIs
  • Kapselung: Daten und Methoden als Einheit
  • Abstraktion: Komplexität reduzieren durch Vereinfachung
  • IHK-relevant: Fundamentales Verständnis für OOP-Entwicklung

Kernkomponenten

  1. Attribute: Dateneigenschaften von Objekten
  2. Nachrichten: Objektkommunikation
  3. Methoden: Verhaltensimplementierung
  4. Persistenz: Datendauerhaftigkeit
  5. Schnittstellen: Definierte Verträge
  6. Kapselung: Daten- und Methodenbündelung
  7. Abstraktion: Komplexitätsreduktion
  8. Polymorphie: Mehrere Formen einer Schnittstelle

Praxisbeispiele

1. Attribute in verschiedenen Sprachen

// Java Attribute
public class Auto {
    // Instanzattribute (pro Objekt)
    private String marke;           // Private Eigenschaft
    protected int baujahr;          // Geschützte Eigenschaft
    public double preis;            // Öffentliche Eigenschaft
    
    // Klassenattribut (für alle Objekte gleich)
    private static int anzahlAutos = 0;
    
    // Konstante
    public static final int MAX_GESCHWINDIGKEIT = 250;
    
    // Konstruktor zur Initialisierung
    public Auto(String marke, int baujahr, double preis) {
        this.marke = marke;
        this.baujahr = baujahr;
        this.preis = preis;
        Auto.anzahlAutos++; // Klassenattribut erhöhen
    }
    
    // Getter und Setter für gekapselte Attribute
    public String getMarke() {
        return marke;
    }
    
    public void setMarke(String marke) {
        this.marke = marke;
    }
    
    public static int getAnzahlAutos() {
        return anzahlAutos;
    }
}
// C# Attribute
public class Mitarbeiter
{
    // Auto-Properties (moderne Syntax)
    public string Name { get; set; }
    public int Alter { get; private set; }  // Nur lesbar von außen
    
    // Volle Property mit Validierung
    private double gehalt;
    public double Gehalt
    {
        get { return gehalt; }
        set
        {
            if (value >= 0)
                gehalt = value;
            else
                throw new ArgumentException("Gehalt kann nicht negativ sein");
        }
    }
    
    // Statische Eigenschaft
    public static string Firma { get; set; } = "TechCorp";
    
    // Konstante
    public const decimal MINDESTGEHALT = 2000m;
    
    public Mitarbeiter(string name, int alter, double gehalt)
    {
        Name = name;
        Alter = alter;
        Gehalt = gehalt;
    }
}
# Python Attribute
class Person:
    # Klassenattribut
    anzahl_personen = 0
    
    def __init__(self, name, alter):
        # Instanzattribute
        self.name = name          # Öffentlich
        self._alter = alter       # Geschützt (Konvention)
        self.__geheim = "data"    # Privat (Name Mangling)
        
        Person.anzahl_personen += 1
    
    # Property für gekapselten Zugriff
    @property
    def alter(self):
        return self._alter
    
    @alter.setter
    def alter(self, wert):
        if wert >= 0:
            self._alter = wert
        else:
            raise ValueError("Alter kann nicht negativ sein")
    
    # Statische Methode
    @staticmethod
    def get_anzahl_personen():
        return Person.anzahl_personen

2. Nachrichten und Methodenaufrufe

// Nachrichten zwischen Objekten
public class Bankkonto {
    private double kontostand;
    private String kontonummer;
    
    public Bankkonto(String kontonummer, double startbetrag) {
        this.kontonummer = kontonummer;
        this.kontostand = startbetrag;
    }
    
    // Methode zum Empfangen von Nachrichten
    public void einzahlen(double betrag) {
        if (betrag > 0) {
            this.kontostand += betrag;
            System.out.println("Einzahlung: " + betrag + "€, neuer Kontostand: " + kontostand + "€");
        }
    }
    
    public boolean abheben(double betrag) {
        if (betrag > 0 && kontostand >= betrag) {
            kontostand -= betrag;
            System.out.println("Abhebung: " + betrag + "€, neuer Kontostand: " + kontostand + "€");
            return true;
        }
        return false;
    }
    
    public double getKontostand() {
        return kontostand;
    }
    
    public String getKontonummer() {
        return kontonummer;
    }
}

// Kunde sendet Nachrichten an Bankkonto
public class Kunde {
    private String name;
    private Bankkonto konto;
    
    public Kunde(String name, Bankkonto konto) {
        this.name = name;
        this.konto = konto;
    }
    
    // Kunde sendet Nachrichten an sein Konto
    public void geldEinzahlen(double betrag) {
        System.out.println(name + " will " + betrag + "€ einzahlen");
        konto.einzahlen(betrag);  // Nachricht senden
    }
    
    public boolean geldAbheben(double betrag) {
        System.out.println(name + " will " + betrag + "€ abheben");
        return konto.abheben(betrag);  // Nachricht senden
    }
    
    public void kontostandPruefen() {
        double stand = konto.getKontostand();  // Nachricht senden
        System.out.println(name + "'s Kontostand: " + stand + "€");
    }
}

// Verwendung der Nachrichten
public class BankingDemo {
    public static void main(String[] args) {
        Bankkonto konto = new Bankkonto("DE123456789", 1000.0);
        Kunde kunde = new Kunde("Max Mustermann", konto);
        
        // Nachrichtenkette
        kunde.geldEinzahlen(500.0);
        kunde.kontostandPruefen();
        
        if (kunde.geldAbheben(200.0)) {
            System.out.println("Abhebung erfolgreich");
        }
        
        kunde.kontostandPruefen();
    }
}

3. Persistenz Implementierung

// Serialisierung für Datei-Persistenz
import java.io.*;
import java.util.*;

public class PersistenzDemo {
    
    // Serialisierbare Klasse
    static class Produkt implements Serializable {
        private static final long serialVersionUID = 1L;
        
        private String id;
        private String name;
        private double preis;
        private transient Date lastModified; // transient = nicht serialisiert
        
        public Produkt(String id, String name, double preis) {
            this.id = id;
            this.name = name;
            this.preis = preis;
            this.lastModified = new Date();
        }
        
        // Getter und toString
        public String getId() { return id; }
        public String getName() { return name; }
        public double getPreis() { return preis; }
        
        @Override
        public String toString() {
            return String.format("Produkt[id=%s, name=%s, preis=%.2f]", id, name, preis);
        }
    }
    
    // Persistenz-Manager
    static class PersistenzManager {
        private String dateiname;
        
        public PersistenzManager(String dateiname) {
            this.dateiname = dateiname;
        }
        
        // Objekte speichern
        public void speichereProdukte(List<Produkt> produkte) throws IOException {
            try (ObjectOutputStream oos = new ObjectOutputStream(
                    new FileOutputStream(dateiname))) {
                oos.writeObject(produkte);
                System.out.println("Produkte gespeichert in " + dateiname);
            }
        }
        
        // Objekte laden
        @SuppressWarnings("unchecked")
        public List<Produkt> ladeProdukte() throws IOException, ClassNotFoundException {
            try (ObjectInputStream ois = new ObjectInputStream(
                    new FileInputStream(dateiname))) {
                List<Produkt> produkte = (List<Produkt>) ois.readObject();
                System.out.println("Produkte geladen aus " + dateiname);
                return produkte;
            }
        }
    }
    
    // JSON-Persistenz (manuell)
    static class JsonPersistenz {
        public static void speichereAlsJson(List<Produkt> produkte, String dateiname) throws IOException {
            try (BufferedWriter writer = Files.newBufferedWriter(Paths.get(dateiname))) {
                writer.write("[\n");
                for (int i = 0; i < produkte.size(); i++) {
                    Produkt p = produkte.get(i);
                    writer.write(String.format(
                        "  {\"id\": \"%s\", \"name\": \"%s\", \"preis\": %.2f}",
                        p.getId(), p.getName(), p.getPreis()
                    ));
                    if (i < produkte.size() - 1) {
                        writer.write(",\n");
                    }
                }
                writer.write("\n]");
            }
            System.out.println("Produkte als JSON gespeichert");
        }
    }
    
    public static void main(String[] args) {
        List<Produkt> produkte = Arrays.asList(
            new Produkt("P001", "Laptop", 999.99),
            new Produkt("P002", "Maus", 29.99),
            new Produkt("P003", "Tastatur", 79.99)
        );
        
        PersistenzManager manager = new PersistenzManager("produkte.ser");
        
        try {
            // Serialisierung
            manager.speichereProdukte(produkte);
            
            // Deserialisierung
            List<Produkt> geladeneProdukte = manager.ladeProdukte();
            geladeneProdukte.forEach(System.out::println);
            
            // JSON-Persistenz
            JsonPersistenz.speichereAlsJson(produkte, "produkte.json");
            
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

4. Schnittstellen und APIs

// Programmierschnittstelle (Interface)
interface DatenbankSchnittstelle {
    // Abstrakte Methoden (ohne Implementierung)
    void verbinden() throws DatenbankException;
    void trennen();
    boolean istVerbunden();
    
    // Abfragemethoden
    List<Map<String, Object>> abfragen(String sql) throws DatenbankException;
    int ausfuehren(String sql) throws DatenbankException;
    
    // Default-Methoden (seit Java 8)
    default void verbindenMitTimeout(int timeout) throws DatenbankException {
        verbinden(); // Standard-Implementierung
    }
}

// Eigene Exception-Klasse
class DatenbankException extends Exception {
    public DatenbankException(String nachricht) {
        super(nachricht);
    }
    
    public DatenbankException(String nachricht, Throwable ursache) {
        super(nachricht, ursache);
    }
}

// Konkrete Implementierung
class MySQLDatenbank implements DatenbankSchnittstelle {
    private boolean verbunden = false;
    private String verbindungsString;
    
    public MySQLDatenbank(String verbindungsString) {
        this.verbindungsString = verbindungsString;
    }
    
    @Override
    public void verbinden() throws DatenbankException {
        try {
            // Simulierte Verbindung
            System.out.println("Verbinde zu MySQL: " + verbindungsString);
            Thread.sleep(1000); // Simuliere Netzwerkverzögerung
            verbunden = true;
            System.out.println("Verbindung hergestellt");
        } catch (InterruptedException e) {
            throw new DatenbankException("Verbindung unterbrochen", e);
        }
    }
    
    @Override
    public void trennen() {
        if (verbunden) {
            System.out.println("Verbindung getrennt");
            verbunden = false;
        }
    }
    
    @Override
    public boolean istVerbunden() {
        return verbunden;
    }
    
    @Override
    public List<Map<String, Object>> abfragen(String sql) throws DatenbankException {
        if (!verbunden) {
            throw new DatenbankException("Nicht verbunden");
        }
        
        System.out.println("Führe aus: " + sql);
        
        // Simuliertes Ergebnis
        List<Map<String, Object>> ergebnis = new ArrayList<>();
        Map<String, Object> zeile = new HashMap<>();
        zeile.put("id", 1);
        zeile.put("name", "Testdaten");
        ergebnis.add(zeile);
        
        return ergebnis;
    }
    
    @Override
    public int ausfuehren(String sql) throws DatenbankException {
        if (!verbunden) {
            throw new DatenbankException("Nicht verbunden");
        }
        
        System.out.println("Führe aus: " + sql);
        return 1; // Simulierte betroffene Zeilen
    }
}

// API-Verwendung
public class ApiDemo {
    public static void main(String[] args) {
        // Polymorphe Verwendung über Interface
        DatenbankSchnittstelle db = new MySQLDatenbank("jdbc:mysql://localhost/test");
        
        try {
            // Über die Schnittstelle arbeiten
            db.verbinden();
            
            if (db.istVerbunden()) {
                List<Map<String, Object>> ergebnis = db.abfragen("SELECT * FROM kunden");
                System.out.println("Ergebnis: " + ergebnis.size() + " Zeilen");
                
                int rows = db.ausfuehren("UPDATE kunden SET status = 'active'");
                System.out.println("Betroffene Zeilen: " + rows);
            }
            
        } catch (DatenbankException e) {
            System.err.println("Datenbankfehler: " + e.getMessage());
        } finally {
            db.trennen();
        }
    }
}

5. Web-API Beispiel

// REST API Controller (Spring Boot Beispiel)
@RestController
@RequestMapping("/api/kunden")
public class KundenAPI {
    
    private final KundenService service;
    
    public KundenAPI(KundenService service) {
        this.service = service;
    }
    
    // GET /api/kunden/{id}
    @GetMapping("/{id}")
    public ResponseEntity<Kunde> getKunde(@PathVariable Long id) {
        try {
            Kunde kunde = service.findeKundeById(id);
            return ResponseEntity.ok(kunde);
        } catch (KundeNotFoundException e) {
            return ResponseEntity.notFound().build();
        }
    }
    
    // POST /api/kunden
    @PostMapping
    public ResponseEntity<Kunde> createKunde(@RequestBody Kunde kunde) {
        Kunde erstellterKunde = service.erstelleKunde(kunde);
        return ResponseEntity.status(HttpStatus.CREATED).body(erstellterKunde);
    }
    
    // PUT /api/kunden/{id}
    @PutMapping("/{id}")
    public ResponseEntity<Kunde> updateKunde(@PathVariable Long id, @RequestBody Kunde kunde) {
        try {
            Kunde aktualisierterKunde = service.aktualisiereKunde(id, kunde);
            return ResponseEntity.ok(aktualisierterKunde);
        } catch (KundeNotFoundException e) {
            return ResponseEntity.notFound().build();
        }
    }
    
    // DELETE /api/kunden/{id}
    @DeleteMapping("/{id}")
    public ResponseEntity<Void> deleteKunde(@PathVariable Long id) {
        service.loescheKunde(id);
        return ResponseEntity.noContent().build();
    }
}

// Datenmodell
class Kunde {
    private Long id;
    private String name;
    private String email;
    private LocalDate geburtsdatum;
    
    // Getter und Setter
    public Long getId() { return id; }
    public void setId(Long id) { this.id = id; }
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public String getEmail() { return email; }
    public void setEmail(String email) { this.email = email; }
    public LocalDate getGeburtsdatum() { return geburtsdatum; }
    public void setGeburtsdatum(LocalDate geburtsdatum) { this.geburtsdatum = geburtsdatum; }
}

OOP-Konzepte im Überblick

Kapselung

// Daten und Methoden werden zu einer Einheit gekapselt
public class Bankkonto {
    private double kontostand;  // Private Daten
    
    public void einzahlen(double betrag) {  // Öffentliche Methode
        if (betrag > 0) {
            kontostand += betrag;
        }
    }
    
    public double getKontostand() {
        return kontostand;
    }
}

Abstraktion

// Komplexe Realität wird vereinfacht
abstract class Fahrzeug {
    protected String marke;
    
    public abstract void beschleunigen();
    public abstract void bremsen();
    
    public void anzeigen() {
        System.out.println("Fahrzeug: " + marke);
    }
}

Polymorphie

// Eine Schnittstelle, viele Implementierungen
interface Tier {
    void macheLaut();
}

class Hund implements Tier {
    public void macheLaut() {
        System.out.println("Wuff!");
    }
}

class Katze implements Tier {
    public void macheLaut() {
        System.out.println("Miau!");
    }
}

// Verwendung
Tier tier1 = new Hund();
Tier tier2 = new Katze();

tier1.macheLaut(); // Wuff!
tier2.macheLaut(); // Miau!

Persistenz-Strategien

Serialisierung

  • Java Serialization: Serializable Interface
  • JSON: Menschlich lesbar, plattformunabhängig
  • XML: Strukturiert, mit Metadaten
  • Binary: Kompakt, schnell

Datenbank-Persistenz

  • Relationale DB: Strukturierte Daten mit SQL
  • NoSQL DB: Flexible Dokumente oder Key-Value
  • ORM: Object-Relational Mapping
  • JPA/Hibernate: Java Persistence API

Cloud-Persistenz

  • Object Storage: S3, Azure Blob Storage
  • Databases-as-a-Service: Firebase, Supabase
  • Caching: Redis, Memcached

API-Typen

Programmierschnittstellen

  • Local APIs: Methoden in gleichen Programm
  • Library APIs: Fremde Bibliotheken
  • Framework APIs: Spring, Django, React

Web-APIs

  • REST: HTTP-Methoden, Statuscodes
  • GraphQL: Flexible Abfragesprache
  • gRPC: Hochperformante RPC
  • WebSocket: Echtzeitkommunikation

Plattform-APIs

  • OS APIs: Windows, Linux, macOS
  • Mobile APIs: Android, iOS
  • Cloud APIs: AWS, Azure, GCP

Vorteile und Nachteile

Vorteile von OOP-Begriffen

  • Strukturierung: Klare Organisation von Code
  • Wiederverwendbarkeit: Komponenten können wiederverwendet werden
  • Wartbarkeit: Modularer Aufbau erleichtert Änderungen
  • Testbarkeit: Isolierte Komponenten sind leicht testbar
  • Skalierbarkeit: Systeme können wachsen

Nachteile

  • Komplexität: Overhead bei kleinen Projekten
  • Lernkurve: Viele Konzepte zu verstehen
  • Performance: Manchmal langsamer als prozeduraler Code
  • Over-Engineering: Gefahr der Überkomplexität

Häufige Prüfungsfragen

  1. Was ist der Unterschied zwischen Attribut und Methode? Attribute sind Eigenschaften/Daten, Methoden sind Verhalten/Funktionen eines Objekts.

  2. Erklären Sie den Begriff Nachricht in der OOP! Nachricht ist die Kommunikation zwischen Objekten, meist als Methodenaufruf implementiert.

  3. Was bedeutet Persistenz in der Programmierung? Daten dauerhaft speichern, sodass sie über Programmlaufzeiten hinweg verfügbar bleiben.

  4. Wozu dienen Schnittstellen (Interfaces)? Definieren Verträge zwischen Komponenten und ermöglichen lose Kopplung und Polymorphie.

Wichtigste Quellen

  1. https://de.wikipedia.org/wiki/Objektorientierte_Programmierung
  2. https://docs.oracle.com/javase/tutorial/java/concepts/
  3. https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/
Zurück zum Blog
Share:

Ähnliche Beiträge