Zusammenfassung Exception werfen:
- Main-App:
- Die Methode, die einen Fehler werfen könnte, wird mit Try + Catch umgeben.
- Utillity -Methode:
- In der Methode wird mit einer If-Abfrage der Fehlerfall eingegrenzt. Dort wird ein Objekt der neu zu erstellenden Fehlerklasse geworfen.
- Fehler-Klasse:
- Eine neue Klasse, die von Exceptions erbt, wir erstellt und auf den Fehlerfall (Logging) angepasst.
Wir bauen Schiffe

Wir legen eine neues Maven Projekt (basierend auf Quickstart) an:

Wir erstellen die Klasse Position im Package de.firma.navigation:

package de.firma.navigation;import java.util.Objects;
public class Position {
//Eigenschaften private double x; private double y; private double z; // Konstruktoren public Position(){ this.x = 0.0; this.y = 0.0; this.z = 0.0; } public Position(double x, double y, double z) { this.x = x; this.y = y; this.z = z; } // Getter- und Setter Methoden public double getX() { return x; } public void setX(double x) { this.x = x; } public double getY() { return y; } public void setY(double y) { this.y = y; } public double getZ() { return z; } public void setZ(double z) { this.z = z; } // Business-Methoden @Override public String toString() { return "Position{" + "x=" + x + ", y=" + y + ", z=" + z + '}'; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Position position = (Position) o; //Wir casten das übergebene Object in das Positions-Object. return Double.compare(position.x, x) == 0 && Double.compare(position.y, y) == 0 && Double.compare(position.z, z) == 0; } @Override public int hashCode() { return Objects.hash(x, y, z); }
}
Klasse Schiff:

Das Schiff weiß nicht, wie es beschleunigt. Das wird später erst in den vererbten Klassen definiert (Segel setzen, Gas geben,…). Daher müssen wir die Methode "erhoeheGeschwindigkeit" abstract machen. Das bedeutet aber, dass wir auch die gesamte Klasse abstrahieren:

package de.firma.fahrzeuge;import de.firma.navigation.Position;
import java.util.Objects;
public abstract class Schiff {
//Eigenschaften
private String name;
private int laenge;
private int breite;
private double brt;
private Position position;
protected double geschwindigkeit;
private double kurs; //Winkel in Gradzahlen
private Ankerstatus ankerstatus;// Konstruktoren public Schiff(String name, int laenge, int breite, double brt, Position position) { this.name = name; this.laenge = laenge; this.breite = breite; this.brt = brt; this.position = position; this.geschwindigkeit = 0.0; this.kurs = 0.0; //Richtung Norden this.ankerstatus = Ankerstatus.GELICHTET; } // Getter- und Setter-Methoden (die meisten Settermethoden sind unnütz, weil sie in den Business-Metoden gesetzt werden. public String getName() { return name; } public void setName(String name) { this.name = name; } public int getLaenge() { return laenge; } public int getBreite() { return breite; } public double getBrt() { return brt; } public void setBrt(double brt) { this.brt = brt; } public Position getPosition() { return position; } public double getGeschwindigkeit() { return geschwindigkeit; } public double getKurs() { return kurs; } public Ankerstatus getAnkerstatus() { return ankerstatus; } // Business-Methoden public void setzAnker(){ this.ankerstatus=Ankerstatus.GESETZT; } public void lichteAnker() { this.ankerstatus = Ankerstatus.GELICHTET; } /** * * @param endgeschwindigkeit ist der Zielwert auf die die Geschwindigkeit erhoeht werden soll * * Dieses nicht implementierbar, da die Antriebsart des Schiffes unklar ist */ public abstract void erhoeheGeschwindikeit(double endgeschwindigkeit); //Nicht implementierbar, da wir noch nicht wissen, wie es das Schiff im Detail macht public abstract void verringereGeschwindigkeit(double endgeschwindigkeit); //dito public void setzeKurs(double kurs){} //TODO: Da muss ich noch ran (Richtung überprüfen, kleiner 0 oder größer 360 ergibt exception public void setzeKurs(Position position) { //TODO: muss ich noch machen } @Override public String toString() { return "Schiff{" + "name='" + name + '\'' + ", laenge=" + laenge + ", breite=" + breite + ", brt=" + brt + ", position=" + position + ", geschwindigkeit=" + geschwindigkeit + ", kurs=" + kurs + ", ankerstatus=" + ankerstatus + '}'; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Schiff schiff = (Schiff) o; return laenge == schiff.laenge && breite == schiff.breite && Double.compare(schiff.brt, brt) == 0 && Double.compare(schiff.geschwindigkeit, geschwindigkeit) == 0 && Double.compare(schiff.kurs, kurs) == 0 && Objects.equals(name, schiff.name) && Objects.equals(position, schiff.position) && ankerstatus == schiff.ankerstatus; } @Override public int hashCode() { return Objects.hash(name, laenge, breite, brt, position, geschwindigkeit, kurs, ankerstatus); }
}
Wir erzeugen die Klasse Motorschiff und müssen die fehlenden Methoden implementieren:

package de.firma.fahrzeuge;import de.firma.navigation.Position;
public class Motorschiff extends Schiff{
// Eigenschaften
private double leistung;
private int anzahlMaschinen;//Konstrutoren public Motorschiff(String name, int laenge, int breite, double brt, Position position, double leistung, int anzahlMaschinen) { super(name, laenge, breite, brt, position); this.leistung = leistung; this.anzahlMaschinen = anzahlMaschinen; } //Getter- und Setter-Methoden public double getLeistung() { return leistung; } public int getAnzahlMaschinen() { return anzahlMaschinen; } // Business-Methoden @Override public void erhoeheGeschwindikeit(double endgeschwindigkeit) { this.geschwindigkeit = endgeschwindigkeit; } @Override public void verringereGeschwindigkeit(double endgeschwindigkeit) { this.geschwindigkeit = endgeschwindigkeit; } @Override public String toString() { return "Motorschiff{" + "leistung=" + leistung + ", anzahlMaschinen=" + anzahlMaschinen + ", geschwindigkeit=" + geschwindigkeit + "} " + super.toString(); }
}
Wir erstellen die Klasse Schiff:
package de.firma.fahrzeuge;import de.firma.navigation.Position;
public class Segelschiff extends Schiff{
// Eigenschaften private double Segelflaeche; private int anzahlMasten; //Konstruktoren public Segelschiff(String name, int laenge, int breite, double brt, Position position, double segelflaeche, int anzahlMasten) { super(name, laenge, breite, brt, position); Segelflaeche = segelflaeche; this.anzahlMasten = anzahlMasten; } // Getter- und Setter Methoden public double getSegelflaeche() { return Segelflaeche; } public int getAnzahlMasten() { return anzahlMasten; } // Business-Methoden @Override public void erhoeheGeschwindikeit(double endgeschwindigkeit) { this.geschwindigkeit = endgeschwindigkeit; } @Override public void verringereGeschwindigkeit(double endgeschwindigkeit) { this.geschwindigkeit = endgeschwindigkeit; } @Override public String toString() { return "Segelschiff{" + "Segelflaeche=" + Segelflaeche + ", anzahlMasten=" + anzahlMasten + "} " + super.toString(); }
}
Jetzt passen wir noch die App-Klasse an:
package de.firma;import de.firma.fahrzeuge.Motorschiff;
import de.firma.navigation.Position;//* Schiffs-App
public class App
{
public static void main( String[] args )
{
System.out.println( "Schiff-Applikation" );
Motorschiff ms1 = new Motorschiff("Titanic", 280,25,38700, new Position(10,25,0),25000,4);
System.out.println( "Schiff-MS1: " + ms1);
}
}
Wir markieren unsere Klassen und generieren ein UML-Diagramm:




Übung:
Und jetzt machen wir es umgekehrt. Wir erhalten ein UML-Diagramm und erstellen daraus die Klassen:

package de.firma.fahrzeuge;public abstract class Fahrzeug {
private double geschwindigkeit; private String position; // Konstruktoren public Fahrzeug(double geschwindigkeit, String position) { this.geschwindigkeit = geschwindigkeit; this.position = position; } public Fahrzeug() { this.geschwindigkeit=0.0; this.position = "Eschweiler"; } // Getter und Better Methoden public double getGeschwindigkeit() { return geschwindigkeit; } public void setGeschwindigkeit(double geschwindigkeit) { this.geschwindigkeit = geschwindigkeit; } public String getPosition() { return position; } public void setPosition(String position) { this.position = position; } // Business Logic: Keine
}

package de.firma.fahrzeuge;import java.time.LocalDate; public class Auto extends Fahrzeug{ //Eigenschaften private String name; private int leistung; private int anzsitze; private LocalDate erstzulassung; //Konstruktoren public Auto() { super(110, "A2 Bielefeld"); this.name = "Trabi"; this.leistung = 24; this.anzsitze = 4; this.erstzulassung = LocalDate.of(1954,4,1); } public Auto(double geschwindigkeit, String position, String name, int leistung, int anzsitze, LocalDate erstzulassung) { super(geschwindigkeit, position); this.name = name; this.leistung = leistung; this.anzsitze = anzsitze; this.erstzulassung = erstzulassung; this.setGeschwindigkeit(110); this.setPosition("A2 Bielefeld"); } public Auto(String name) { } // Getter- und Setter public String getName() { return name; } public void setName(String name) { this.name = name; } public int getLeistung() { return leistung; } public void setLeistung(int leistung) { this.leistung = leistung; } public int getAnzsitze() { return anzsitze; } public void setAnzsitze(int anzsitze) { this.anzsitze = anzsitze; } public LocalDate getErstzulassung() { return erstzulassung; } public void setErstzulassung(LocalDate erstzulassung) { this.erstzulassung = erstzulassung; } // Busineslogic @Override public String toString() { return "Auto{" + "name='" + name + '\'' + ", leistung=" + leistung + ", anzsitze=" + anzsitze + ", erstzulassung=" + erstzulassung + "} " + super.toString(); } }

Cabrio: package de.firma.fahrzeuge;import java.time.LocalDate;
public class Cabrio extends Auto {
private int vdauer;
private boolean vstatus;//Konstruktoren public Cabrio() { super(); this.vdauer = 120; this.vstatus = false; } public Cabrio( String name) { super(name); } public Cabrio(String name, int leistung, int anzsitze, LocalDate erstzulassung, double geschwindigkeit, String position, int vdauer, boolean vstatus) { super(geschwindigkeit, position, name, leistung, anzsitze, erstzulassung); this.vdauer = 120; this.vstatus = false; } // Getter und Setter Methoden public int getVdauer() { return vdauer; } public void setVdauer(int vdauer) { this.vdauer = vdauer; } public boolean isVstatus() { return vstatus; } // Business Logik @Override public String toString() { return "Cabrio{" + "vdauer=" + vdauer + ", vstatus=" + vstatus + "} " + super.toString(); }
}

ZweisitzerCabrio: package de.firma.fahrzeuge;import java.time.LocalDate;
public class ZweisitzerCabrio extends Cabrio{
protected boolean notsitz;// Konstruktoren public ZweisitzerCabrio() { super(); this.notsitz = false; } public ZweisitzerCabrio(String name) { super (name); this.setName(name); } public ZweisitzerCabrio(String name, int leistung, int anzsitze, LocalDate erstzulassung, double geschwindigkeit, String position, int vdauer, boolean vstatus, boolean notsitz) { super(name, leistung, anzsitze, erstzulassung, geschwindigkeit, position, vdauer, vstatus); this.notsitz = notsitz; } // Getter und Setter Methoden public boolean isNotsitz() { return notsitz; } public void setNotsitz(boolean notsitz) { this.notsitz = notsitz; } //Businesslogik @Override public String toString() { return "ZweisitzerCabrio{" + "notsitz=" + notsitz + "} " + super.toString(); }
}
Singelton
Neues Projekt:

Wir legen das Package "design" an und erzeugen dort die Klasse Singleton:

Nun erstellen wir die Main-Klasse SingletonApp, fügen folgenden Inhalt ein und lassen das Ganze laufen. Wir erhalten 4 verschiedene Objekte:

Eine Eigenschaft die wir auf static setzten wird im Compiler nur ein mal erzeugt.
Wir schreiben den Code ein bisschen um und das Objekt wird nur einmal erzeugt:

Achtung: Dieses Singleton ist nicht threadsave.
Semaphoren sind Bearbeitungsprozesse, die nicht unterbrochen werden dürfen. Vor der Semaphore baut sich eine Warteschlange auf, es darf immer nur einer rein. Das Wort synchronized ist so eine Semaphore. Wir fügen es vor dem static ein:
//Methoden public synchronized static Singleton getInstance() { if (obj == null) { obj = new Singleton(); } return obj; }
——————
Disclaimer
Alles was ich mitschrieb und verstanden habe ist ohne Gewähr.
Besten Dank an unseren
Trainer: Hans-Joachim Blanke blanke@4point.de

Mehr dazu im nächsten Blog von mir.
Gruß, Achim Mertens