Klassen / Objekte, Getter/Setter, Konstruktor, Packages, Static, Sichtbarkeiten

Grundlagen

  • Objekt-Orientierte-Programmierung (OOP) ist ein Prinzip.

  • Menschen denken in Objekten und Zusammenhängen.

  • OOP wendet diese Denkweise auf die Programmierung an.

  • Konzept: Nur ein Objekt darf auf seine eigenen Daten zugreifen (Information Hiding).

  • Weitere Erklärungen und Übungen zu Java und OOP: https://www.w3schools.com/java/java_oop.asp

Grundlagen

  • Eine class ist die Definition eines Objekts. Quasi ein Bauplan
    (z.B. Die Klasse Person)
  • Ein Object ist die "Instanziierung" der Klasse mit konkreten Daten.
    (z.B. Florian, Dominic)

Klasse

  • Daten-Definition
  • Methoden
class Student {
  int age;
  String name;
  Address address;
  // ...

  boolean hasBirthdayToday() {
    // ...
  }
}

Object / Instanz

  • Kennt seine Klasse
  • Hält konkrete Daten
Student student = new Student();

if (student.hasBirthdayToday()) {
  System.out.println("Happy Birthday!!");
}

Daten müssen dem Objekt nach der Erzeugung erst gegeben werden.

static: Zugriff auf die Definition

static Variablen sind für alle Instanzen gleich:

class Student {
  static int age = 32; // Alle Studenten sind jetzt 32 Jahre alt. Macht das Sinn?
}

Ohne static gilt die Variable nur für die jeweilige Instanz

class Student {
  int age = 32; // Jeder Student hat sein eigenes Alter
}

Also: static nur da benutzen wo man wirklich für alle Instanzen den selben Wert haben will

class Student {
  static final int MINIMUM_AGE = 18;
  int age = 32;
}

this: Zugriff auf die Instanz

Referenz auf die konkreten Daten in der Methodendefinition der Klasse.

class Student {
  LocalDate birthdate;

  boolean hasBirthdayToday() {
    int birthday = this.birthdate.getDayOfYear();
    int today = LocalDate.now().getDayOfYear();
    return (birthday == today);
  }
}

Getter/Setter

  • Information Hiding mit z.B. private
  • Nur das Objekt selbst darf auf private Daten und Methoden zugreifen.
  • Zugriff und Änderung nach Außen über "getter" und "setter" Methoden.
  • Java initialisiert alles mit null/0/false
  • Uninitialisierte Daten führen üblicherweise zu Fehlern
class Student {
    private String name;

    String getName() {
        return name;
    }

    void setName(String name) {
        this.name = name;
    }
}

Aufgabe: Klassen 1

  1. Lege eine Klasse Student an und überlege dir drei Eigenschaften
  2. Schreibe Methoden, um die Eigenschaften zu setzen und abzufragen

Konstruktor

  • Initialisiert das Objekt
  • Kann Parameter haben
  • Definieren wir keinen Konstruktor, wird automatisch ein leerer Default Konstruktor erzeugt
  • Methode mit Name der Klasse ohne Rückgabewert
  • Wird einmalig beim Erzeugen aufgerufen
public class Student {
    private String name;

    // Konstruktor
    public Student(String name) {
        this.name = name;
    }
}

Student student = new Student("Frank");

packages

  • Ordnerstruktur im Projekt
  • Strukturierung und Kapselung des Projekts
  • Eine Klasse aus einem anderen Package muss zur Verwendung importiert werden.
// Datei: model/Student.java
package model;

public class Student {
    private String name;

    public Student(String name){
        this.name = name;
    }

    public String getName(){
        return name;
    }
}

// Datei: AppMain.java
import model.Student;

class AppMain {

  public static void main(String[] args) {
    Student student = new Student("name");
    System.out.println(student.getName());
  }
}

Sichtbarkeiten (Access Modifiers)

Den Zugriff von Außen regulieren

Modifier Class Package Subclass World
public ✅ ✅ ✅ ✅
protected ✅ ✅ ✅ ❌
(no modifier)* ✅ ✅ ❌ ❌
private ✅ ❌ ❌ ❌

*aka "package protected"

Sichtbarkeiten (Access Modifiers)

public class Student {
  protected static final int AGE_OF_MAJORITY = 18;

  private int age;

  public Student(int age) {
    this.age = age;
  }

  public int getAge() {
    return this.age;
  }

  public boolean isAllowedToDrink() {
    this.getAge() >= AGE_OF_MAJORITY;
  }
}

Aufgabe: Package

  1. Verschiebe deine Student Klasse in ein model Package und passe die Sichtbarkeiten und Referenzen an
  2. Schreibe eine Methode toString welche alle Eigenschaften eines Studenten als String zurückgibt
  3. Schreibe für deinen Student Klasse einen Konstruktor und verwende ihn

Basis Objekt-Methoden

  • equals
    • Überprüft ob this Objekt einem übergebenen Objekt gleicht
  • hashCode
    • Generiert "eindeutige" Nummer für das Objekt anhand seiner Daten
    • Datenstrukturen (HashMap)
    • Wichtig: Immer überschreiben, wenn equals überschrieben wird
  • toString
    • Gibt eine Text-Repräsentation des Objekts aus.

Aufgabe: Basis Objekt-Methoden

  1. Generiere für deine Klasse equals
  2. Generiere für deine Klasse hashCode
  3. Nutze die equals Methode im Test

Aufgabe: Random Student

Erstelle eine Klasse StudentDB mit folgenden Eigenschaften

  1. Der Konstruktor nimmt ein Array von Studenten entgegen
  2. Jeder Student hat einen Namen und eine Id
  3. Die Methode getAllStudents gibt alle Studenten als Array zurück
  4. Die Methode toString() gibt alle Studenten formatiert als String zurück
  5. Die Methode randomStudent() gibt einen zufälligen Studenten zurück (Nutze für den Zufall Math.random())

Schreibe für alle Methoden Tests (bis auf randomStudent() )

Bonus: Schreibe eine add und eine remove Methode, um Studenten hinzuzufügen und zu entfernen

Further reading (externe Ressourcen)