/**
* AlgDs WS99 Aufgabe38.
* Klassenhierarchie der Wiener Hofburg.
*
* Entlohnung
* +--Hofzwerg
* | +-- ErsterHofzwerg
* | +-- ZweiterHofzwerg
* +--Zeitarbeiter
*   +-- Schoenschreiber
*   +-- Erbpompbrist
*
* @author Christian Semrau, 14.01.2000
* Christian.Semrau@student.uni-magdeburg.de
*/
public class ChS_Aufg38 {
/** "Kleine" Testumgebung. */
public static void main(String args[])
{
    Entlohnung[]liste= new Entlohnung[10];
    liste[0] = new ErsterHofzwerg("Adam");
    liste[1] = new ErsterHofzwerg("Berta");
    liste[2] = new ZweiterHofzwerg("Christian");
    liste[3] = new Schoenschreiber("Detlef", 40);
    liste[4] = new Schoenschreiber("Emil", 60);
    liste[5] = new Erbpompbrist("Franziska", 40);
    liste[6] = new Erbpompbrist("Gustav", 80);
    liste[7] = new Erbpompbrist("Hans", 45);
    liste[8] = new ZweiterHofzwerg("Ingo");
    liste[9] = new ZweiterHofzwerg("Jana");
    out(liste);
}
public static void out(Entlohnung[] liste) {
    if (liste==null) return;
    for (int i=0; i<liste.length; i++)
    if (liste[i]!=null)
    System.out.println(liste[i].name()
    +":\t"+liste[i].gehalt()+" - "+liste[i].steuern()
    +" = "+(liste[i].gehalt()-liste[i].steuern()));
}
}
/**
* AlgDs WS99 Aufgabe 38.
* Abstrakte Basisklasse.
* Deklariert freibetrag() und gehalt() abstract, steuern().
* Konstruktor nimmt name.
*
* @author Christian Semrau, 14.01.2000
*/
abstract class Entlohnung {
double grundfreibetrag=100; String name;
public Entlohnung(String name) { this.name=name; }
/** Abstrakter Freibetrag (der Teil des Gehalts, der nicht versteuert wird). */
public abstract double freibetrag();
/** Abstraktes Gehalt (Einnahmen pro [was eigentlich? Jahr, Monat?]). */
public abstract double gehalt();
public String name() { return name; }
/** Steuern (45% des zu versteuernden Gehalts). */
public double steuern() {
    return Math.max(0,gehalt()-freibetrag())*0.45;
    /* wenn gehalt() < freibetrag(), dann keine Steuern */
}
}
/**
* Ueberschreibt freibetrag() und gehalt(), deklariert festbetrag() und
* zusatzfreibetrag() abstract.
*/
abstract class Hofzwerg extends Entlohnung{
public Hofzwerg(String name) { super(name); }
/** Festbetrag (festes Gehalt). */
public abstract double festbetrag();
/** Freibetrag (Grundfreibetrag + Zusatzfreibetrag). */
public double freibetrag() { return grundfreibetrag + zusatzfreibetrag(); }
/** Gehalt (Festbetrag). */
public double gehalt() { return festbetrag(); }
/** Zusatzfreibetrag (zusaetzlich steuerfreies Gehalt). */
public abstract double zusatzfreibetrag();
}
/** Ueberschreibt festbetrag() und zusatzfreibetrag(). */
class ErsterHofzwerg extends Hofzwerg{
public ErsterHofzwerg(String name) { super(name); }
public double festbetrag() { return 350; }
public double zusatzfreibetrag() { return 120; }
}
/** Ueberschreibt festbetrag() und zusatzfreibetrag(). */
class ZweiterHofzwerg extends Hofzwerg{
public ZweiterHofzwerg(String name) { super(name); }
public double festbetrag() { return 450; }
public double zusatzfreibetrag() { return 140; }
}
/**
* Ueberschreibt freibetrag() und gehalt(), deklariert stundenlohn() abstract,
* zeitfreibetrag(), Konstructor nimmt name und stunden.
*/
abstract class Zeitarbeiter extends Entlohnung {
double stunden;
public Zeitarbeiter(String name,double st) { super(name); stunden=st; }
/** Freibetrag (Grundfreibetrag + Zeitfreibetrag).
*/
public double freibetrag() { return grundfreibetrag + zeitfreibetrag(); }
/** Gehalt (Stunden * Stundenlohn). */
public double gehalt() { return stunden * stundenlohn(); }
/** Abstrakter Stundenlohn. */
public abstract double stundenlohn();
public double zeitfreibetrag() { return 130; }
}
/** Ueberschreibt stundenlohn(). */
class Erbpompbrist extends Zeitarbeiter{
public Erbpompbrist(String name,double stunden) { super(name,stunden); }
/** Stundenlohn (10). */
public double stundenlohn() { return 10; }
}
/** Ueberschreibt stundenlohn(). */
class Schoenschreiber extends Zeitarbeiter{
public Schoenschreiber(String name,double stunden) { super(name,stunden); }
/** Stundenlohn (8). */
public double stundenlohn() { return 8; }
}
