Lab-03 — Vererbung: Mitarbeiter, Firma

1. Teil: Zu erstellen ist folgende Klassenhierarchie

Links stehendes '-' oder rotes Quadrat steht für private Attribut,
'+' oder grüner Kreis kennzeichnet eine public Methode,
'…()' es sind nicht alle erforderlichen Methoden angegeben

mypkgMitarbeitername: StringsozVersNr: String // einfacher String genügtberechneGehalt() : float // liefert hier 0;equals(Object o) : booleantoString() : String // soll auch Gehalt anzeigenprintInfo()Angestellter// ist ein Mitarbeitergehalt : float // monatliches GrundgehaltberechneGehalt() : float // gibt Grundgehalt zurück…()TeilzeitAngestellterstundenProWoche : float // zw. 10 und 30berechneGehalt() : float // Ang-gehalt * stdProWo / 38.5…()AbteilungsleiteranzahlMitarbeiter : int // Anz. geleiteter Mitarb.// (ist ein Angestellter)berechneGehalt() : float // Angest. + anzahlMitarbeiter*100…()WerksvertragsAngestellterstunden : float // pro Monat zu arbeitende Stundenstundenlohn : float//(ist ein Mitarbeiter)berechneGehalt() : float // stunden * stundenlohn…()

Für diese Klassen gilt:

  • Die Java Namenskonventionen beachten! Nur wirklich erforderliche get- und set-Methoden (public oder private?) realisieren.

  • Übergabewerte sind auf Plausibilität zu prüfen. Bei einem ungültigen Wert ist, wenn kein Default-Wert sinnvoll erscheint, eine selbst definierte Exception zu werfen (lernen wir noch, vorerst ein System.out…).

  • Konstruktoren: für alle Klassen sind geeignete Konstruktoren zu erstellen. Der Konstruktor einer abgeleiteten Klasse ruft zur Initialisierung der geerbten Attribute den Konstruktor der Elternklasse auf!

  • toString(): diese Methode gibt die Eigenschaften des betreffenden Objektes als Text zurück. Zum Aufbau des Rückgabetextes ist auch die toString()-Methode der Elternklasse zu verwenden.

  • printInfo(): gibt den mittels toString() erzeugten Text zu Testzwecken auf die Konsole aus.

2. Teil: Klasse Firma1 mit Mitarbeiter-Array:

mypkgFirma1// ist eine Klasse zur Verwaltung der Mitarbeitername : String // Name der Firmamitarbeiterliste : Mitarbeiter[]Konstruktor(maxMitarb: int)einstellen(neuerMitarbeiter : Mitarbeiter) : booleanentlassen(szvnr : String) : booleanprintMitarbeiter(gehalt : float)printMitarbeiter(nurAbteilungsleiter : boolean)sucheMitarbeiter(name : String)
Array mitarbeiterliste

Da beim Array-Erstellen eine fixe Größe festgelegt wird, muss geklärt werden, welche Zellen gerade leer und welche voll sind.
In der ersten Klasse wurden dafür 2 Verfahren besprochen: mit LEER_WERT oder mit lückenlosem Array und Füllstand.

einstellen()

fügt neuen Mitarbeiter hinzu. Es ist sicherzustellen, dass kein Mitarbeiterobjekt mehrmals eingefügt wird.
Dazu muss das Array durchlaufen werden und jeder Eintrag auf IDENTITÄT (also wirklich mit '==') verglichen werden. Weiters ist auf null zu prüfen, da auf null-Referenzen keine Methoden aufgerufen werden können (NullPointerException!!!).

entlassen(szvnr : String)

boolean, entfernt den Mitarbeiter mit der angegebenen Sozialversicherungsnummer aus der Firma. Rückgabewert: true…falls gefunden, false…wenn es keinen Mitarbeiter mit der angegebenen Nummer gibt

printMitarbeiter(gehalt : float)

gibt mit Hilfe der printInfo()-Methoden eine Liste aller Angestellten aus, deren Gehalt größer-gleich dem angegebenen Wert ist. Bei 0 werden alle Mitarbeiter ausgegeben.

printMitarbeiter(nurAbteilungsleiter : boolean)

gibt mit Hilfe der printInfo()-Methoden alle Abteilungsleiter aus. Übergabeparameter: false: alle Mitarbeiter, true: nur Abteilungsleiter (Tipp: instanceof)

sucheMitarbeiter(name : String)

Mitarbeiter, diese Methode sucht den Mitarbeiter mit dem angegebenen Namen und gibt das erste gefundene Objekt zurück. Wie sieht der Rückgabewert sinnvollerweise aus, wenn kein passender Angestellter gefunden wird?

3. Teil: Klasse Firma2 mit ArrayList

mypkgFirma2// ist eine Klasse zur Verwaltung der Mitarbeitername : String // Name der Firmamitarbeiterliste : List<Mitarbeiter>..Konstruktor()einstellen(neuerMitarbeiter : Mitarbeiter)entlassen(szvnr : String) : booleanprintMitarbeiter(gehalt : float)printMitarbeiter(nurAbteilungsleiter : boolean)sucheMitarbeiter(name : String)

4. Teil: Test-Klasse

Zuletzt erstellen wir eine Klasse my.pkg.Test.

Diese enthält die main(..)-Methode, in der alle Schritte beginnen.

Innerhalb der main(..)-Methode werden Instanzen von Firma, Mitabeitern aller Unterklassen erzeugt, der Firma zugeordnet (mit Methode firma1.einstellen(..) ), etc.

Dann werden im Idealfall alle Methoden aller Klassen aufgerufen, um einen ersten Einblick über die Funktion oder Fehler zu erhalten.

In BlueJ konnten wir direkt interaktiv Objekte erzeugen und an diesen Methoden ausführen.

Das können wir nun nicht mehr (ausgenommen im Debugger), daher ist das Erstellen von Tests extrem wichtig.

Für interaktives Arbeiten wären z.B. Klasse java.util.Scanner oder ein GUI erforderlich.

Das Erstellen von GUIs (mit JavaFX) wird noch vor Weihnachten Thema sein.

Hinweise zur Test-Klasse:

Es ist sinnvoll, die Tests in mehrere Methoden zu gliedern – z.B. Tests der einzelnen Mitarbeiter-Klassen in testenMitarb(), Testen der Klasse Firma (Hinzufügen, Entfernen, etc.) in z.B. testenFa().

Alternativ könnte man die Tests gültiger Aktionen in Methode testsNiceCases() und von Aktionen, die Fehler verursachen sollten, in testsBadCases() zusammenfassen.

5. UML-Diagramm kombiniert (weiterführende Info)

Hier das komplette UML-Diagramm (incl. Firma und Test). Assoziationen sind hier der guten Unterscheidbarkeit wegen strichliert dargestellt (lt. Standard sollten die Linien für Assoziationen durchgehend sein, strichliert bedeutet eigentlich schwächere Abhängigkeit – Methodenparameter etc.).

mypkgMitarbeiternamesozVersNr // einfacher String genügtberechneGehalt() : float // liefert hier 0;toString() : String // soll auch Gehalt anzeigenprintInfo()Angestellter// ist ein Mitarbeitergehalt : float // monatliches GrundgehaltberechneGehalt() : float // gibt Grundgehalt zurück…()TeilzeitAngestellterstundenProWoche : float // zw. 10 und 30// Angestelltengehalt * stundenProWoche / 38.5// (ist ein Angestellter)berechneGehalt() : float…()AbteilungsleiteranzahlMitarbeiter // Anz. geleiteter Mitarb.// (ist ein Angestellter)berechneGehalt() : float // Angest. + anzahlMitarbeiter*100…()WerksvertragsAngestellterstunden : float // pro Monat zu arbeitende Stundenstundenlohn : float//(ist ein Mitarbeiter)berechneGehalt() : float // stunden * stundenlohn…()Firma// ist eine Klasse zur Verwaltung der Mitarbeitername : String // Name der Firmamitarbeiterliste : Mitarbeiter[]einstellen(neuerMitarbeiter : Mitarbeiter)entlassen(szvnr : String) : booleanprintMitarbeiter(gehalt : float)printMitarbeiter(nurAbteilungsleiter : boolean)sucheMitarbeiter(name : String)Testtesten1()testen2()...()