Demo Klasse Auto samt Javadoc, Testklasse

Dies ist eine Umsetzung von Labor – Auto mit kleinen Variationen.

Die Klasse Auto ist recht ausführlich mit Javadoc-Kommentaren dokumentiert und kann auch diesbezüglich als Beispiel dienen.

1. Datei 'Auto.java'

mit kleinen Adaptionen, z.B. printInfo mit Parameter titel, einige Hilfmethoden.

//3456789a123456789b123456789c123456789d123456789e123456789f123456789g123456789h123456789i123456789j

/**
 * Einfache Klasse mit Tanken, Reichweite etc. <br>
 *
 * Unabhängig davon: Beispiel Javadoc-Aufzählung:
 * <ul>
 * <li>Punkt 1</li>
 * <li>Punkt 2</li>
 * <li>Punkt 3</li>
 * </ul>
 *
 * Beispiel SVG-Grafik direkt im Code:<br>
 * <svg width="200" height="100">
<circle cx="150" cy="50" r="40" stroke="green" stroke-width="4" fill="yellow" />
</svg>
 * @author Max Renkin
 * @version 2022-11-22
 */
public class Auto
{
    private float normverbrauch = -1;
    private int tankgroesse = -1;
    private float tankinhalt = 0;
    private int kilometerstand = 0;
    private String kennzeichen = null;

    /**
     * Parameterloser Standardkonstruktor. <br>
     * Da keine Werte für die Instanzvariablen zur
     * Verfügung stehen, sind sinnvolle Anfangswerte zu wählen.<br>
     * Z.B.:
     *   normverbrauch = 4.9<br>
     *   tankgroesse = 50   ... MUSS vor tankinhalt gesetzt werden (wird dort als Obergrenze benötigt!)<br>
     *   tankinhalt = 33.5<br>
     *   kilometerstand = 40000<br>
     *   kennzeichen = null
     */
    public Auto() {
        setNormverbrauch(4.9f);
        setTankgroesse(50);
        setTankinhalt(33.5f);
        setKilometerstand(40000);
        setKennzeichen(null);
    }

    /**
     * Setzt die Instanzvariablen auf die angegebenen Werte. <br>
     * Achtung: dabei sind natürlich Überprüfungen / Korrekturen durchzuführen
     * (diese sollten an die entsprechenden set-Methoden delegiert werden).
     *
     * @param normverbrauch Verbrauch in l/100km nach normiertem Test
     *        (kann nur einmalig gesetzt werden)
     * @param tankgroesse Kapazität des Tanks
     * @param tankinhalt aktueller Tankinhalt in Litern (>= 0)
     * @param kilometerstand km-Stand auf Tacho
     * @param kennzeichen das amtliche Autokennzeichen
     *
     */
    public Auto(float normverbrauch, int tankgroesse, float tankinhalt,
    int kilometerstand, String kennzeichen) {
        setNormverbrauch(normverbrauch);
        setTankgroesse(tankgroesse);
        setTankinhalt(tankinhalt);
        setKilometerstand(kilometerstand);
        setKennzeichen(kennzeichen);
    }

    /**
     * Setzt Normverbrauch, nur ein <b>einziges Mal</b> nutzbar.
     * Einmalige Nutzbarkeit durch check, ob noch der ungültige
     * Initialisierungswert gesetzt ist (-1)!
     * @param normverbrauch Verbrauch (2..20) in l/100km, z.B.: 4,9 [l/100km]
     */
    private void setNormverbrauch(float normverbrauch) {
        if (this.normverbrauch > 0) { // !!this.!! Attr. ggü. Stdwert -1 schon geändert
            System.out.println("ERR in setNormverbrauch(..) - wurde schon gesetzt!");
        } else if (normverbrauch < 2.0 || normverbrauch > 20.0) {
            System.out.println("ERR in setNormverbrauch(..) - ungültiger Wert (2..20): "
                + normverbrauch + " -> bleibt " + this.normverbrauch);
        } else {
            this.normverbrauch = normverbrauch;
        }
    }

    /**
     * Setzt die Tankgroesse. <br>
     * Maximaler Tankinhalt (in Litern), soll bei der Instanziierung (Erzeugen
     * eines Objektes) einmalig gesetzt und danach unveränderbar sein.
     * @param tankgroesse die vorgesehene Tankgröße
     */
    private void setTankgroesse(int tankgroesse) {
        if (this.tankgroesse > 0) {  // this. !!
            System.out.println("ERR in setTankgroesse(..) - Wert schon gesetzt"
                    + " - nur einmalig erlaubt!");
        } else if (tankgroesse < 5 || tankgroesse > 100) {
            System.out.println("ERR in setTankgroesse(..) - ungültiger Wert (5..100): "
                + tankgroesse + " -> bleibt " + this.tankgroesse);
        } else {
            this.tankgroesse = tankgroesse;
        }
    }

    /**
     * Setzt den aktuellen Tankinhalt.<br>
     * Kann nicht < 0 oder > Tankgröße sein.<br>
     * Achtung: Tankgröße MUSS DAVOR GESETZT SEIN --> Fehlerprfg: this.tankgroesse < 0 !!
     * @param Tankinhalt in Litern
     */
    private void setTankinhalt(float tankinhalt) {
        if (tankinhalt < 0) {
            System.out.println("ERR in setTankinhalt(..) - Wert < 0: " + tankinhalt
                + " -> bleibt " + this.tankinhalt);
        } else if (this.tankgroesse < 0) {
            System.out.println("ERR in setTankinhalt(..) - Tankgröße noch nicht gesetzt!");
        } else if (tankinhalt > this.tankgroesse) {
            System.out.println("ERR in setTankinhalt(..) - Tankinhalt (" + tankinhalt
                + ") > Tankgröße (" + this.tankgroesse + ") -> bleibt " + this.tankinhalt);
        } else {
            this.tankinhalt = tankinhalt;
        }
    }

    /**
     * Setzt Attribut kilometerstand.
     * @param kilometerstand zu setzender Wert (0..999_999 - kann nur erhöht werden!)
     */
    private void setKilometerstand(int kilometerstand) {
        if (kilometerstand < 0 || kilometerstand > 999_999) {
            System.out.println("ERR in setKilometerstand(..) - ungültiger Wert (0..999_999): "
                + kilometerstand + " -> bleibt " + this.kilometerstand);
        } else if (kilometerstand < this.kilometerstand) {
            System.out.println("ERR in setKilometerstand(..) - Stand (" + this.kilometerstand
                + ") kann nicht VERKLEINERT werden (auf " + kilometerstand + ")");
        } else {
            this.kilometerstand = kilometerstand;
        }
    }

    /**
     * Setzt das Kennzeichen. <br>
     * Bei ungültigem Parameterwert bleibt der alte Wert bestehen.
     * @param kennzeichen null (nicht angemeldet) oder String mit Min-Länge 6 Zeichen
     */
    private void setKennzeichen(String kennzeichen) {
        if (kennzeichen != null && kennzeichen.length() < 6) {
            System.out.println("ERR in setKennzeichen(..) - Wert-Länge zu kurz (>= 6): "
                + kennzeichen + " -> bleibt " + this.kennzeichen);
        } else {
            this.kennzeichen = kennzeichen;
        }
    }

    /**
     * Füllt den Tank randvoll und gibt die getankte Treibstoffmenge zurück.
     * @return getankte Treibstoffmenge in Litern
     */
    public float tanken() {
        float getankt = this.tankgroesse - this.tankinhalt;
        this.tankinhalt = this.tankgroesse;
        return getankt;
    }

    // Nützliche Zusatzmethode, liefert tatsächliche Tank-Menge zurück.
    public float tanken(float liter) {
        float getankt = liter;
        if (liter < 0) {
            System.out.println("ERR in tanken(float) - liter < 0: " + liter);
            getankt = 0;
        } else if (this.tankinhalt + getankt > this.tankgroesse) {
            getankt = this.tankgroesse - this.tankinhalt;
        }
        this.tankinhalt += getankt;
        return getankt;
    }

    /**
     * Füllt angeg. Treibstoffmenge in den Tank (zum angeg. Literpreis). <br>
     * <p><b>Achtung:</b> Tankgröße beachten (Tankmenge nicht größer als Platz im Tank)</p>
     * @param preis Treibstoffpreis/Liter
     * @param liter zum Tanken geplante Treibstoffmenge
     * @return zu bezahlender Gesamtbetrag
     */
    public float tanken(float preis, float liter) {
        return tanken(liter) * preis;
    }

    /**
     * Tankt für einen bestimmten, angegebenen Geldbetrag (z.B.: 20 Euro).
     * <p>D.h. hier ist die dafür erhältliche Treibstoffmenge zu berechnen und natürlich
     * auch wieder die Tankgröße zu berücksichtigen.</p>
     * @return tatsächlich getankte Treibstoffmenge in Litern.
     */
    public float tanken(float preis, int betrag) {
        float liter = betrag/preis;
        return tanken(liter);
    }

    /**
     * Fährt soweit, als es der aktuelle Tankinhalt zulässt. <br>
     * Dabei wird natürlich der Kilometerstand entsprechend erhöht
     * und der Tankinhalt auf 0 gesetzt.<br>
     * Berechnung (siehe auch Formel unten):
     * liter = km * normverbrauch[l/100km]/100  --> km = 100*liter/normverbrauch
     * @return tatsächlich zurückgelegte Strecke.
     */
    public int fahren() {
        int km = getRestreichweite();
        this.kilometerstand += km;
        this.tankinhalt = 0;
        return km;
    }

    /**
     * Fährt die angegebene Strecke.
     * Dabei erhöht sich der Kilometerstand und reduziert sich der Tankinhalt entsprechend.<br>
     * <b>Achtung:</b> wird eine zu große Strecke eingegeben, dann kann natürlich nicht wirklich
     * so weit gefahren werden.<br>
     * Berechnung: normverbrauch in l/100km --> verbrauchJeKm = normverbrauch/100<br>
     * liter = km * verbrauchJeKm    (siehe auch Formel oben)
     * @param strecke die zu fahrende Strecke
     * @return tatsächlich zurückgelegte Strecke
     */
    public int fahren(int strecke) {
        int echtKm = strecke;
        int maxKm = getRestreichweite();
        if (strecke > maxKm) {
            echtKm = maxKm;
            this.tankinhalt = 0;
        } else {
            this.tankinhalt -= echtKm * normverbrauch/100;
        }
        this.kilometerstand += echtKm;
        return echtKm;
    }

    /**
     * Gibt den aktuellen Kilometerstand zurück.
     */
    public int getKilometerstand( ) {
        return this.kilometerstand;
    }

    /**
     * Gibt den aktuellen Tankinhalt in Litern zurück.
     */
    public float getTankinhalt( ) {
        return this.tankinhalt;
    }

    /**
     * Berechnet die Restreichweite (basierend auf dem Normverbrauch und dem aktuellen
     * Tankinhalt) und gibt diesen Wert zurück.
     * @return Rest-Reichweite in km (basierend auf aktuellem Tankinhalt)
     */
    public int getRestreichweite( ) {
        return (int) (100*this.tankinhalt/normverbrauch);
    }

    /**
     * Hilfsmethode zur Ausgabe der Kennzeichen-Information.
     * @return der Text zum Kennzeichen-Inhalt lt. printInfo-Dokumentation
     */
    public String kennzInfo() {
        String info = "";
        if (kennzeichen == null) {
            info = "nicht angemeldet";
        } else {
            info += "\"" + kennzeichen + "\"";
            if (kennzeichen.endsWith("TX")) {
                info += " - ist Taxi";
            }
        }
        return info;
    }

    /**
     * Gibt die Informationen zu diesem Fahrzeug auf der Konsole aus. <br>
     * ACHTUNG: Erweiterung gegenüber Lab-08: Parameter 'titel'<br>
     * Zum Beispiel:<br>
     * ----------------<br>
     * Auto mit Normverbrauch: 4.9 l/100km<br>
     * Tankinhalt/Tankgröße: 33.5/50 l<br>
     * Kilometerstand: 40000, Kennzeichen: “W 1234 TX“ - ist Taxi<br>
     * Zum Kennzeichen:
     * <ul>
     *   <li>gibt es kein Kennzeichen, dann lautet die letzte Zeile der Ausgabe:
     *     Kennzeichen: nicht angemeldet</li>
     *   <li>für normale Kennzeichen: nur Kennzeichen ausgegeben, z.B.:
     *     Kennzeichen: “TU 423 AL“</li>
     *   <li>bei Taxis endet das Kennzeichen mit "TX", hier Ausgabe z.B.:
     *     Kennzeichen: “W 1234 TX“ - ist Taxi</li>
     *   @param titel wenn null, wird String mit 16 '-' ausgegeben, anderenfalls
     *                "--- " + titel + " ---" (zur Info, was zuvor geschehen ist)
     * </ul>
     */
    public void printInfo(String titel) {
        if (titel != null) {
            System.out.println("--- " + titel + " ---");
        } else {
            System.out.println("----------------");
        }
        System.out.println("Auto mit Normverbrauch: " + normverbrauch + " l/100km");
        System.out.println("Tankinhalt/Tankgröße: " + tankinhalt + "/" + tankgroesse + " l");
        System.out.println("Km-Stand: " + kilometerstand + ", Kennzeichen: " + kennzInfo());
        System.out.println();
    }
}

2. Datei 'TestenAuto.java'

Die Testklasse ist dzt. noch nicht fertig, sollte aber eine Idee liefern.

public class TestenAuto
{
    // instance variables - replace the example below with your own
    public TestenAuto()
    {
        testAuto();
    }


    public void testAuto() {
        testAutoNiceCases();
        testAutoBadCases();
    }

    public void testAutoNiceCases() {
    // Konstruktor-Kopf-Kopie, um ParamListe richtig füllen zu können!!!
    // public Auto(float normverbrauch, int tankgroesse, float tankinhalt,
    //..               int kilometerstand, String kennzeichen) {
        Auto a1 = new Auto(6.0f, 50, 0.0f, 0, null);
        a1.printInfo("Auto(6.0f, 50, 0.0f, 0, null) erzeugt:");
        Auto a2 = new Auto(4.5f, 55, 20.0f, 0, "HL-12345XY");
        a2.printInfo("Auto(4.5f, 55, 20.0f, 0, 'HL-12345XY') erzeugt");
        Auto a3 = new Auto(4.0f, 40, 0.0f, 0, "W-12345TX");
        a3.printInfo("Auto(4.0f, 40, 0.0f, 0, 'W-12345TX') erzeugt");

        a1.tanken(1.5f, 10);
        a1.fahren(100);
        //System.out.println("abc".substring(1,3));
        a1.printInfo("getankt: Preis=1.5, Liter=10; fahren: 100km");

        //TODO: fertigstellen
    }

    public void testAutoBadCases() {
        //TODO: implementieren
    }
}