4.4 Beispiel "Personen - Mitarbeiter - Organisationen"

Es gibt Personen, die Kunden oder Mitarbeiter eines Unternehmens sind.
Jeder Mitarbeiter gehört zu genau 1 Organisation, jede Organisation wird von einem Manager geleitet, jeder Manager gehört zu der von ihm geleiteten Organisation.
Derzeit gibt es Abteilungen und Projekte als organisatorische Einheiten.
Ein Mitarbeiter kann in eine andere Organisation überwechseln, ein Manager kann eine neue Organisation übernehmen.
Jede Person muss zumindest einen Namen und ein Geschlecht haben.
Jeder Mitarbeiter und Manager hat eine unternehmensweit eindeutige Personalnummer.

Jeder Mitarbeiter erhält einen Grundgehalt pro Monat. Dies ist sein monatlicher Verdienst.
Jeder Manager erhält zusätzlich zu seinem Grundgehalt eine monatliche Prämie, die aus dem Bruttogewinn der von ihm geleiteten Organisation berechnet wird (dieser Gewinnanteil ist ein fixer Prozentsatz für alle Manager). Der monatliche Verdienst eines Managers ist daher die Summe von Grundgehalt und Prämie. Allfällige weitere Prämien oder Gehälter (z.B. 13. und 14. Gehalt) werden der Einfachheit halber ignoriert.
Die Grundgehälter sind durch eine fix vorgegebene Obergrenze in ihrer Höhe beschränkt. Diese Obergrenzen sind für Mitarbeiter und für Manager unterschiedlich.

Der Bruttogewinn einer Organisation errechnet sich aus:
Umsatz – Sachkosten – Personalkosten ohne Prämien.

Die Personalkosten ohne Prämien sind einfach alle Grundgehälter der Mitarbeiter der Organisation.
Die tatsächlichen Personalkosten beinhalten zusätzlich noch die Prämie des Leiters der Organisation.
Der (tatsächliche) Gewinn einer Organisation berücksichtigt auch die tatsächlichen Personalkosten.
Sachkosten + Personalkosten ergeben die Gesamtkosten (einmal mit und einmal ohne Prämie).

Der Umsatz einer Abteilung sind die Einnahmen der Abteilung.
Der Umsatz eines Projekts pro Jahr berechnet sich aus:
(geplanter Jahresgewinn * geplante Lebensdauer in Jahren) / geplante Entwicklungszeit in Jahren.

Bemerkung:
Der Einfachheit halber betrachten wir ein sehr einfaches statisches System, d.h. die Mitarbeiter, die Manager und die Kunden sind fix vorgegeben! Es ist nicht möglich, dass ein einfacher Mitarbeiter Manager werden kann! Ebenso ist es nicht möglich, dass ein Mitarbeiter oder ein Manager gleichzeitig Kunde sein kann!
Weiters ist ein Kunde immer eine Person - daher wird Vererbung für die Beziehung Kunde – Person verwendet. Tatsächlich ist "Kunde" nur eine von vielen Rollen, die eine Person spielen kann. Besser wäre dafür die Verwendung einer Aggregation. Analoges gilt für die Beziehung Mitarbeiter – Person.

In den folgenden Klassendefinitionen dienen die Text-Hervorhebungen (Fettdruck, Schriftart, Schriftgröße usw.) nur der optischen Aufbereitung und haben keinerlei syntaktische Bedeutung!

Zu den Java-Klassen
Person
Kunde
Mitarbeiter
Manager
Organisation
Abteilung
Projekt
Zu den C#-Klassen
Person
Kunde
Mitarbeiter
Manager
Organisation
Abteilung
Projekt
Zu den Smalltalk-Klassen
Person
Kunde
Mitarbeiter
Manager
Organisation
Abteilung
Projekt
Zu den Anwendungsprogrammen
Java - Testklasse
Java - Programmklasse
C# - Testklasse
C# - Programmklasse
Smalltalk


4.4.1 Klassendefinitionen - Java

Klasse Person
/* * Person.java */ package at.beringer.oopBuch.organisation; import java.time.LocalDate; /** Jede Instanz dieser Klasse repräsentiert eine natürliche Person. <p> Zusätzlich wurde die 'toString'-Methode implementiert. </p> <hr /> @since August 1999 @version April 2002 (überschreiben 'toString') @version <br />Juli 2003 (öffentliche Klassenkonstante mit Initialisierungsmethode) @version <br />April 2014 (aktualisieren Java 8 - 'GregorianCalendar' ersetzen) @see OrganisationTesten @see Kunde @see Mitarbeiter @see at.beringer.oopBuch.einfacheBsp.Person @author Beringer Alfred */ public class Person { // ------------------------------------------------------------------------- // Klassenkonstante // ------------------------------------------------------------------------- /** Kennzeichen für das Geschlecht "männlich" */ public static final char MAENNLICH; /** Kennzeichen für das Geschlecht "weiblich" */ public static final char WEIBLICH; /** Anrede für Personen männlichen Geschlechts */ public static final String ANREDEMAENNLICH; /** Anrede für Personen weiblichen Geschlechts */ public static final String ANREDEWEIBLICH; // ------------------------------------------------------------------------- // Instanzattribute // ------------------------------------------------------------------------- private String name; private LocalDate geburtsdatum; private char geschlecht; private String adresse; // ------------------------------------------------------------------------- // Klassenkonstruktor // ------------------------------------------------------------------------- /** Klassenkonstruktor (Klassen-Initialisierungsblock). <p> Die Werte für nicht initialisierte Klassenkonstante könnten von externen Datenquellen geholt werden (z.B. von einer Datei, einer Datenbank oder von einer Properties-Datei). <p> Der Einfachheit halber werden die Werte jedoch fix vorgegeben. </p> <dl> <dt>Hinweis:</dt> <dd>Nur in dieser Methode sind Zuweisungen für Klassenkonstante erlaubt!</dd> </dl> */ static { MAENNLICH = 'M'; WEIBLICH = 'W'; ANREDEMAENNLICH = "Herr"; ANREDEWEIBLICH = "Frau"; } // ------------------------------------------------------------------------- // Konstruktoren // ------------------------------------------------------------------------- /** Eine Person muss mindestens ein Geburtsdatum und ein Geschlecht haben. Zusätzlich können der Name und die Adresse angegeben werden. <br /> Standardkonstruktor nicht erlaubt! @param name Name @param geburtsdatum Geburtsdatum @param geschlecht Geschlecht @param adresse Adresse */ public Person(String name, LocalDate geburtsdatum, char geschlecht, String adresse) { setName(name); setGeburtsdatum(geburtsdatum); setGeschlecht(geschlecht); setAdresse(adresse); } // ---------- /** Eine Person muss mindestens ein Geburtsdatum und ein Geschlecht haben. Zusätzlich kann der Name angegeben werden. <br /> Die Adresse wird mit einer leeren Zeichenkette initialisiert. <br /> Standardkonstruktor nicht erlaubt! @param name Name @param geburtsdatum Geburtsdatum @param geschlecht Geschlecht */ public Person(String name, LocalDate geburtsdatum, char geschlecht) { this(name, geburtsdatum, geschlecht, ""); } // ---------- /** Eine Person muss mindestens ein Geburtsdatum und ein Geschlecht haben. <br /> Name und Adresse werden mit einer leeren Zeichenkette initialisiert. <br /> Standardkonstruktor nicht erlaubt! @param geburtsdatum Geburtsdatum @param geschlecht Geschlecht */ public Person(LocalDate geburtsdatum, char geschlecht) { this("", geburtsdatum, geschlecht, ""); } // ------------------------------------------------------------------------- // Öffentliche Zugriffsmethoden (Get- und Set-Methoden) // ------------------------------------------------------------------------- /** Liefert den Namen der Person. @return Name */ public String getName() { return name; } // ---------- /** Ändert den Namen der Person. @param name neuer Name */ public void setName(String name) { this.name = name; } // ------------------------------------------------------------------------- /** Liefert das Geburtsdatum der Person. Ein LocalDate-Objekt ist immutable (wie ein String-Objekt) und kann daher wie ein elementarer Datentyp verwendet werden. Insbesondere kann es direkt als Parameter in Methoden verwendet werden (es ist nicht notwendig, eine Kopie als Parameter zu uebergeben). @return Geburtsdatums */ public LocalDate getGeburtsdatum() { // Originalobjekt kann zurückgegeben werden return geburtsdatum; } // ------------------------------------------------------------------------- /** Liefert das Geschlecht der Person. @return Geschlecht */ public char getGeschlecht() { return geschlecht; } // ------------------------------------------------------------------------- /** Liefert die Adresse der Person. @return Adresse */ public String getAdresse() { return adresse; } // ---------- /** Ändert die Adresse der Person. @param adresse neue Adresse */ public void setAdresse(String adresse) { this.adresse = adresse; } // ------------------------------------------------------------------------- // Sonstige öffentliche Instanzmethoden // ------------------------------------------------------------------------- /** Liefert die Anrede für die Person. @return Anrede entsprechend dem Geschlecht bzw. leere Zeichenkette, falls das Geschlecht falsch ist */ public String anrede() { if (geschlecht == MAENNLICH) { return ANREDEMAENNLICH; } if (geschlecht == WEIBLICH) { return ANREDEWEIBLICH; } return ""; } // ------------------------------------------------------------------------- /** Berechnet das Alter der Person. @return Alter in Jahren */ public int alterBerechnen() { LocalDate heute = LocalDate.now(); return heute.getYear() - geburtsdatum.getYear(); } // ------------------------------------------------------------------------- // Methode 'toString' // ------------------------------------------------------------------------- /** Überschreiben der Methode 'String Object.toString()'. <p> Liefert eine beschreibende Text-Darstellung einer Instanz der Klasse: <pre> Person [ Name = ..., Geschlecht = ..., Geburtsdatum = tt. mm. jj, Adresse = ... ] </pre> </p> @see java.lang.Object#toString() @return Zeichenkette, die eine Instanz beschreibt */ @Override public String toString() { StringBuilder text = new StringBuilder(); LocalDate datum = getGeburtsdatum(); // Zugriff auf Attribute nur über Zugriffsmethoden (Datenkapselung)! text.append(getClass().getName()).append( " [ Name = " ).append(getName() ).append( ", Geschlecht = " ).append(getGeschlecht()).append( ", Geburtsdatum = ").append( datum.getDayOfMonth()).append(". ").append( datum.getMonthValue()).append(". ").append( datum.getYear() ).append( ", Adresse = " ).append(getAdresse() ).append( " ]" ); return new String(text); } // ------------------------------------------------------------------------- // Private Zugriffsmethoden // ------------------------------------------------------------------------- /** Ändert das Geburtsdatum der Person. <p> Das neue Geburtsdatum muss vor dem aktuellen Tagesdatum liegen. </p> @param geburtsdatum neues Geburtsdatum @return true, wenn 'geburtsdatum' ein gültiges Geburtsdatum ist */ private boolean setGeburtsdatum(LocalDate geburtsdatum) { LocalDate heute = LocalDate.now(); if (geburtsdatum.isBefore(heute)) { // Parameterobjekt kann direkt verwendet werden this.geburtsdatum = geburtsdatum; return true; } // ungültiges Geburtsdatum this.geburtsdatum = heute; return false; } // ------------------------------------------------------------------------- /** Ändert das Geschlecht der Person. <p> Prüft, ob das Geschlecht gültig ist (Kennzeichen muss ein gültiges Geschlechtskennzeichen - männlich bzw. weiblich - sein). </p> @param geschlecht neues Geschlecht (männlich oder weiblich) @return true, wenn 'geschlecht' ein gültiges Geschlechtskennzeichen ist */ private boolean setGeschlecht(char geschlecht) { this.geschlecht = geschlecht; return ((geschlecht == MAENNLICH) || (geschlecht == WEIBLICH)) ? true : false; } }


Klasse Kunde
/* * Kunde.java */ package at.beringer.oopBuch.organisation; import java.time.LocalDate; /** Instanzen dieser Klasse repräsentieren Kunden. <hr /> @since August 1999 @version April 2014 (aktualisieren Java 8 - 'GregorianCalendar' ersetzen) @see Person @author Beringer Alfred */ public class Kunde extends Person { // ------------------------------------------------------------------------- // Instanzattribute // ------------------------------------------------------------------------- private float jahresumsatz = 0.0f; private float kreditlimit = 0.0f; // ------------------------------------------------------------------------- // Konstruktoren // ------------------------------------------------------------------------- /** @see Person#Person(String, LocalDate, char, String) @param name Name @param geburtsdatum Geburtsdatum @param geschlecht Geschlecht @param adresse Adresse */ public Kunde(String name, LocalDate geburtsdatum, char geschlecht, String adresse) { super(name, geburtsdatum, geschlecht, adresse); } // ---------- /** @see Person#Person(String, LocalDate, char) @param name Name @param geburtsdatum Geburtsdatum @param geschlecht Geschlecht */ public Kunde(String name, LocalDate geburtsdatum, char geschlecht) { this(name, geburtsdatum, geschlecht, ""); } // ---------- /** @see Person#Person(LocalDate, char) @param geburtsdatum Geburtsdatum @param geschlecht Geschlecht */ public Kunde(LocalDate geburtsdatum, char geschlecht) { this("", geburtsdatum, geschlecht, ""); } // ------------------------------------------------------------------------- // Zugriffsmethoden (Get- und Set-Methoden) // ------------------------------------------------------------------------- /** Liefert den Jahresumsatz des Kunden. @return Jahresumsatz */ public float getJahresumsatz() { return jahresumsatz; } // ---------- /** Ändert den Jahresumsatz des Kunden. @param jahresumsatz neuer Jahresumsatz */ public void setJahresumsatz(float jahresumsatz) { this.jahresumsatz = jahresumsatz; } // ------------------------------------------------------------------------- /** Liefert das Kreditlimit des Kunden. @return Kreditlimit */ public float getKreditlimit() { return kreditlimit; } // ---------- /** Ändert das Kreditlimit des Kunden. @param kreditlimit neues Kreditlimit */ public void setKreditlimit(float kreditlimit) { this.kreditlimit = kreditlimit; } }


Klasse Mitarbeiter
/* * Mitarbeiter.java */ package at.beringer.oopBuch.organisation; import java.time.LocalDate; import java.lang.reflect.*; /** Instanzen dieser Klasse repräsentieren Mitarbeiter einer Organisation. <hr /> @since August 1999 @version April 2014 (aktualisieren Java 8 - 'GregorianCalendar' ersetzen) @see Person @see Organisation @see OrganisationTesten @author Beringer Alfred */ public class Mitarbeiter extends Person { // ------------------------------------------------------------------------- // Klassenattribute // ------------------------------------------------------------------------- /** Klassenattribut für 'Mitarbeiter' und für alle 'Mitarbeiter'-Subklassen. */ private static int LetztePersNr = 0; /** Klassenattribut für Höchstgehalt, die für jede 'Mitarbeiter'-Subklasse unterschiedlich sein kann (entspricht somit einem Klasseninstanzattribut). @see Manager#MaxGehalt */ private static float MaxGehalt; // ------------------------------------------------------------------------- // Instanzattribute // ------------------------------------------------------------------------- private int persNr; private String stellung = "Mitarbeiter"; private float grundgehalt; private Organisation organisation; // ------------------------------------------------------------------------- // Klassenkonstruktor // ------------------------------------------------------------------------- /** Klassenkonstruktor (Klassen-Initialisierungsblock). <p> Die Werte für nicht initialisierte Klassenattribute könnten von externen Datenquellen geholt werden (z.B. von einer Datei, einer Datenbank oder von einer Properties-Datei). <p> Der Einfachheit halber werden die Werte jedoch fix vorgegeben. </p> */ static { setMaxGehalt(4500.0f); } // ------------------------------------------------------------------------- // Konstruktoren // ------------------------------------------------------------------------- /** @see Person#Person(String, LocalDate, char, String) @param name Name @param geburtsdatum Geburtsdatum @param geschlecht Geschlecht @param adresse Adresse */ public Mitarbeiter(String name, LocalDate geburtsdatum, char geschlecht, String adresse) { super(name, geburtsdatum, geschlecht, adresse); persNrNeu(); setGrundgehalt(1200.0f); } // ---------- /** @see Person#Person(String, LocalDate, char) @param name Name @param geburtsdatum Geburtsdatum @param geschlecht Geschlecht */ public Mitarbeiter(String name, LocalDate geburtsdatum, char geschlecht) { this(name, geburtsdatum, geschlecht, ""); } // ---------- /** @see Person#Person(LocalDate, char) @param geburtsdatum Geburtsdatum @param geschlecht Geschlecht */ public Mitarbeiter(LocalDate geburtsdatum, char geschlecht) { this("", geburtsdatum, geschlecht, ""); } // ------------------------------------------------------------------------- // Zugriffsmethoden (Get- und Set-Methoden) // ------------------------------------------------------------------------- /** Liefert die (eindeutige) Personalnummer des Mitarbeiters. @return Personalnummer */ public int getPersNr() { return persNr; } // ------------------------------------------------------------------------- /** Liefert die Stellung (Position) des Mitarbeiters in der Organisation. @return Stellung */ public String getStellung() { return stellung; } // ---------- /** Ändert die Stellung (Position) des Mitarbeiters in der Organisation. @param stellung neue Stellung */ public void setStellung(String stellung) { this.stellung = stellung; } // ------------------------------------------------------------------------- /** Liefert das Grundgehalt des Mitarbeiters. @return Grundgehalt */ public float getGrundgehalt() { return grundgehalt; } // ---------- /** Ändert das Grundgehalt des Mitarbeiters (soferne es nicht größer als das maximale Gehalt ist). <p> Mit Hilfe des Reflection-APIs wird die korrekte 'getMaxGehalt'-Klassenmethode aufgerufen (ohne Reflection-API würde immer die 'getMaxGehalt'-Methode der Klasse 'Mitarbeiter' aufgerufen werden!). <br /> Ohne Reflection-API müsste diese Instanzmethode in jeder Subklasse identisch definiert (d.h. identisch überschrieben) werden. </p> @param grundgehalt neues Grundgehalt - darf nicht größer als das maximale Gehalt sein @return true, wenn Grundgehalt geändert wird */ public boolean setGrundgehalt(float grundgehalt) { Class c = this.getClass(); Method m; Float rueck; float maxGehalt; try { // gesuchte Methode hat keine Parameter, daher Parameter-Array leer m = c.getMethod("getMaxGehalt", new Class[0]); /* aufgerufene Methode ist eine Klassenmethode, daher 'null' aufgerufene Methode hat keine Parameter, daher Argument-Array leer Rückgabetyp ist immer 'Object', daher Konvertierung auf 'Float' */ rueck = (Float) m.invoke(null, new Object[0]); // Konvertierung in elementaren Datentyp maxGehalt = rueck.floatValue(); } catch (Exception e) { maxGehalt = getMaxGehalt(); // dies ist immer die // 'Mitarbeiter'-Methode! } if (grundgehalt <= maxGehalt) { this.grundgehalt = grundgehalt; return true; } System.out.println("Grundgehalt von " + this.getClass() + " kann maximal sein: " + maxGehalt); return false; } // ------------------------------------------------------------------------- /** Liefert die Organisation des Mitarbeiters. @return Organisation */ public Organisation getOrganisation() { return organisation; } // ---------- /** Ändert die Organisation des Mitarbeiters und fügt Mitarbeiter in die neue Organisation ein, falls er dieser noch nicht angehört. @param organisation neue Organisation */ public void setOrganisation(Organisation organisation) { if ( this.organisation != null ) { this.organisation.removeMitarbeiter(this); } this.organisation = organisation; if ( (this.organisation != null) && !this.organisation.getMitarbeiterliste().contains(this) ) { this.organisation.addMitarbeiter(this); } } // ------------------------------------------------------------------------- // Sonstige Instanzmethoden // ------------------------------------------------------------------------- /** Liefert die Anrede des Mitarbeiters in der Organisation. <br /> Überschreibt die Methode 'anrede' der Klasse 'Person'. @see Person#anrede() @return Anrede entsprechend dem Geschlecht und der Stellung des Mitarbeiters */ @Override public String anrede() { return super.anrede() + " " + getStellung() + " " + getName(); } // ------------------------------------------------------------------------- /** Liefert den Verdienst des Mitarbeiters (entspricht bei einfachen Mitarbeitern dem Grundgehalt). @return Verdienst */ public float verdient() { return getGrundgehalt(); } // ------------------------------------------------------------------------- // Private Instanzmethoden // ------------------------------------------------------------------------- /** Ordnet jedem Mitarbeiter eine eindeutige (fortlaufende) Personalnummer zu. @return true, wenn Mitarbeiter noch keine Personalnummer hat */ private boolean persNrNeu() { if (persNr == 0) { setLetztePersNr(getLetztePersNr() + 1); persNr = getLetztePersNr(); return true; } // Mitarbeiter hat bereits eine Personalnummer return false; } // ------------------------------------------------------------------------- // Klassenmethoden // ------------------------------------------------------------------------- /** Liefert die derzeit letzte Personalnummer aller Mitarbeiter. @return letzte zugeordnete Personalnummer */ protected static int getLetztePersNr() { return LetztePersNr; } // ---------- /** Ändert die derzeit letzte Personalnummer aller Mitarbeiter. @param letztePersNr neue letzte zugeordnete Personalnummer */ private static void setLetztePersNr(int letztePersNr) { LetztePersNr = letztePersNr; } // ------------------------------------------------------------------------- /** Liefert das Höchstgehalt eines einfachen Mitarbeiters. @return Höchstgehalt */ public static float getMaxGehalt() { return MaxGehalt; } // ---------- /** Ändert die Höchstgrenze für das Grundgehalt eines einfachen Mitarbeiters. @param maxGehalt neues Höchstgehalt */ public static void setMaxGehalt(float maxGehalt) { MaxGehalt = maxGehalt; } }


Klasse Manager
/* * Manager.java */ package at.beringer.oopBuch.organisation; import java.time.LocalDate; /** Instanzen dieser Klasse repräsentieren Manager einer Organisation. <hr /> @since August 1999 @version April 2014 (aktualisieren Java 8 - 'GregorianCalendar' ersetzen) @see Person @see Mitarbeiter @see Organisation @see OrganisationTesten @author Beringer Alfred */ public class Manager extends Mitarbeiter { // ------------------------------------------------------------------------- // Klassenattribute // ------------------------------------------------------------------------- /** Klasseninstanzattribut für Höchstgehalt (Klassenattribut aus der Klasse 'Mitarbeiter'). @see Mitarbeiter#MaxGehalt */ private static float MaxGehalt; /** Klassenattribut für Gewinnanteil. */ private static float Gewinnanteil; // ------------------------------------------------------------------------- // Instanzattribute // ------------------------------------------------------------------------- private Organisation geleiteteOrganisation; // ------------------------------------------------------------------------- // Klassenkonstruktor // ------------------------------------------------------------------------- /** Klassenkonstruktor (Klassen-Initialisierungsblock). <p> Die Werte für nicht initialisierte Klassenattribute könnten von externen Datenquellen geholt werden (z.B. von einer Datei, einer Datenbank oder von einer Properties-Datei). <p> Der Einfachheit halber werden die Werte jedoch fix vorgegeben. </p> */ static { setMaxGehalt(15000.0f); setGewinnanteil(0.05f); } // ------------------------------------------------------------------------- // Konstruktoren // ------------------------------------------------------------------------- /** @see Person#Person(String, LocalDate, char, String) @param name Name @param geburtsdatum Geburtsdatum @param geschlecht Geschlecht @param adresse Adresse */ public Manager(String name, LocalDate geburtsdatum, char geschlecht, String adresse) { super(name, geburtsdatum, geschlecht, adresse); setStellung("Leiter"); setGrundgehalt(5000.0f); } // ---------- /** @see Person#Person(String, LocalDate, char) @param name Name @param geburtsdatum Geburtsdatum @param geschlecht Geschlecht */ public Manager(String name, LocalDate geburtsdatum, char geschlecht) { this(name, geburtsdatum, geschlecht, ""); } // ---------- /** @see Person#Person(LocalDate, char) @param geburtsdatum Geburtsdatum @param geschlecht Geschlecht */ public Manager(LocalDate geburtsdatum, char geschlecht) { this("", geburtsdatum, geschlecht, ""); } // ------------------------------------------------------------------------- // Zugriffsmethoden (Get- und Set-Methoden) // ------------------------------------------------------------------------- /** Liefert die vom Manager geleitete Organisation. @return geleitete Organisation */ public Organisation getGeleiteteOrganisation() { return geleiteteOrganisation; } // ---------- /** Ändert die vom Manager geleitete Organisation, ändert gegebenenfalls seinen Status in der Organisation. @param geleiteteOrganisation neue geleitete Organisation */ public void setGeleiteteOrganisation(Organisation geleiteteOrganisation) { if ( getOrganisation() != null ) { getOrganisation().removeMitarbeiter(this); } setOrganisation(geleiteteOrganisation); this.geleiteteOrganisation = geleiteteOrganisation; if ( geleiteteOrganisation != null ) { geleiteteOrganisation.setLeiter(this); } } // ------------------------------------------------------------------------- // Sonstige Instanzmethoden // ------------------------------------------------------------------------- /** Liefert den Verdienst des Managers (= Grundgehalt + Prämie). <p> Überschreibt die Methode 'verdient' der Klasse 'Mitarbeiter'. </p> @see Mitarbeiter#verdient() @return Verdienst */ @Override public float verdient() { return getGrundgehalt() + ( geleiteteOrganisation.gewinnOhnePraemie() * getGewinnanteil() ); } // ------------------------------------------------------------------------- // Klassenmethoden // ------------------------------------------------------------------------- /** Liefert das Höchstgehalt eines Managers. <p> Da die Klassen 'Manager' und 'Mitarbeiter' jeweils eigene Klassenvariablen 'MaxGehalt' haben, müssen auch in jeder Klasse eigene Zugriffsmethoden definiert werden. </p> @see Mitarbeiter#getMaxGehalt() @return Höchstgehalt */ public static float getMaxGehalt() { return MaxGehalt; } // ---------- /** Ändert die Höchstgrenze für das Grundgehalt eines Managers. @param maxGehalt neues Höchstgehalt */ public static void setMaxGehalt(float maxGehalt) { MaxGehalt = maxGehalt; } // ------------------------------------------------------------------------- /** Liefert den Gewinnanteil eines Managers. @return Gewinnanteil */ public static float getGewinnanteil() { return Gewinnanteil; } // ---------- /** Ändert den Gewinnanteil eines Managers. @param gewinnanteil neuer Gewinnanteil */ public static void setGewinnanteil(float gewinnanteil) { Gewinnanteil = gewinnanteil; } }


Klasse Organisation
/* * Organisation.java */ package at.beringer.oopBuch.organisation; import java.util.*; /** Abstrakte Klasse für organisatorische Einheiten in einem Unternehmen. <br /> Solche organisatorischen Einheiten können Abteilungen, Projekte usw. sein. <hr /> @since August 1999 @version Jänner 2002 (Set) @version <br />August 2004 (Fehler bei 'leiter == null' behoben, Zugriffsmethoden für 'mitarbeiterliste' nicht mehr 'public') @version <br />Dezember 2004 (JDK 5.0: Generics für 'mitarbeiterliste', Verwendung von 'for-each') @version <br />Juli 2014 (JDK 8.0: Datenstrom ('stream') + Aggregat-Operationen 'forEach', 'mapToDouble' und 'sum') @see Mitarbeiter @see Manager @see Abteilung @see Projekt @see OrganisationTesten @author Beringer Alfred */ public abstract class Organisation { // ------------------------------------------------------------------------- // Instanzattribute // ------------------------------------------------------------------------- private String name; private Manager leiter; private Set<Mitarbeiter> mitarbeiterliste = new HashSet<>(); private float sachkosten = 0.0f; // ------------------------------------------------------------------------- // Zugriffsmethoden (Get- und Set-Methoden) // ------------------------------------------------------------------------- /** Liefert den Namen der Organisation. @return Name */ public String getName() { return name; } // ---------- /** Ändert den Namen der Organisation. @param name neuer Name */ public void setName(String name) { this.name = name; } // ------------------------------------------------------------------------- /** Liefert den Leiter der Organisation. @return Leiter der Organisation */ public Manager getLeiter() { return leiter; } // ---------- /** Ändert den Leiter der Organisation. @param leiter neuer Leiter der Organisation */ public void setLeiter(Manager leiter) { this.leiter = leiter; } // ------------------------------------------------------------------------- /** Liefert die Sachkosten. @return Sachkosten */ public float getSachkosten() { return sachkosten; } // ---------- /** Ändert die Sachkosten. @param sachkosten neue Sachkosten */ public void setSachkosten(float sachkosten) { this.sachkosten = sachkosten; } // ------------------------------------------------------------------------- /** Liefert die Mitarbeiterliste der Organisation. <p> Eine öffentliche Get-Methode sollte ein unveränderbares 'Collection'-Objekt retournieren ('Collections.unmodifiableSet(...)' - siehe JDK-Dokumentation). </p> @return Mitarbeiterliste */ protected Set<Mitarbeiter> getMitarbeiterliste() { return this.mitarbeiterliste; } // ---------- /** Fügt einen neuen Mitarbeiter hinzu; wird gegebenenfalls aus seiner vorhergehenden Organisation entfernt. @param einMitarbeiter neuer (hinzuzufügender) Mitarbeiter */ public void addMitarbeiter(Mitarbeiter einMitarbeiter) { Organisation bisherigeOrg = einMitarbeiter.getOrganisation(); if ( (bisherigeOrg != null) && (bisherigeOrg != this) ) { bisherigeOrg.removeMitarbeiter(einMitarbeiter); einMitarbeiter.setOrganisation(this); } mitarbeiterliste.add(einMitarbeiter); } // ---------- /** Entfernt einen Mitarbeiter. @param einMitarbeiter zu entfernender Mitarbeiter */ public void removeMitarbeiter(Mitarbeiter einMitarbeiter) { mitarbeiterliste.remove(einMitarbeiter); } // ------------------------------------------------------------------------- // Sonstige Instanzmethoden // ------------------------------------------------------------------------- /** Erstellt eine Übersichtsliste aller Mitarbeiter + Leiter der Organisation. */ public void druckeAlleMitarbeiter() { System.out.println(this.getClass() + ": " + getName()); if (leiter == null || leiter.getClass() != Manager.class) { System.out.println("noch kein Manager als Leiter ernannt."); } else { System.out.println("geleitet von: " + leiter.getName()); } System.out.println("Anzahl Mitarbeiter = " + mitarbeiterliste.size()); // Datenstrom ('stream') + Aggregat-Operation 'forEach' (seit JDK 8.0): mitarbeiterliste.stream() .forEach(ma -> System.out.println(ma.anrede() + " (Grundgehalt = " + ma.getGrundgehalt() + ")")); /* ---------- for-each-Schleife (seit JDK 5.0): for (Mitarbeiter ma : mitarbeiterliste) { System.out.println(ma.anrede() + " (Grundgehalt = " + ma.getGrundgehalt() + ")"); } ---------- */ /* ---------- mit Iterator: Iterator iterMA = mitarbeiterliste.iterator(); while (iterMA.hasNext()) { Mitarbeiter ma = (Mitarbeiter) iterMA.next(); System.out.println(ma.anrede() + " (Grundgehalt = " + ma.getGrundgehalt() + ")"); } ---------- */ } // ------------------------------------------------------------------------- /** Erstellt eine Übersichtsliste der Gesamtkosten der Organisation. */ public void druckeKostenUebersicht() { System.out.println(this.getClass() + ": " + getName() + " Kostenuebersicht"); System.out.println( "---------------------------------------------------------------------------"); System.out.println("Mitarbeiter \t\t\t Grundgehalt \t Verdienst"); System.out.println( "---------------------------------------------------------------------------"); // Datenstrom ('stream') + Aggregat-Operation 'forEach' (seit JDK 8.0): mitarbeiterliste.stream() .forEach(ma -> System.out.println(ma.anrede() + " \t\t " + ma.getGrundgehalt() + " \t " + ma.verdient())); /* ---------- for-each-Schleife (seit JDK 5.0): for (Mitarbeiter ma : mitarbeiterliste) { System.out.println(ma.anrede() + " \t\t " + ma.getGrundgehalt() + " \t " + ma.verdient()); } ---------- */ /* ---------- mit Iterator: Iterator iterMA = mitarbeiterliste.iterator(); while (iterMA.hasNext()) { Mitarbeiter ma = (Mitarbeiter) iterMA.next(); System.out.println(ma.anrede() + " \t\t " + ma.getGrundgehalt() + " \t " + ma.verdient()); } ---------- */ System.out.println( "---------------------------------------------------------------------------"); System.out.println("Personalkosten = \t " + personalkosten()); System.out.println("Praemie = \t " + praemie()); System.out.println("Sachkosten = \t " + getSachkosten()); System.out.println("Gesamtkosten = \t " + gesamtkosten()); System.out.println("Gewinn = \t " + gewinn()); } // ------------------------------------------------------------------------- /** Berechnet die Personalkosten aus den Grundgehältern der Mitarbeiter. @return Personalkosten ohne Prämie */ public float personalkostenOhnePraemie() { float summe = 0.0f; // Datenstrom ('stream') + Aggregat-Operationen // 'mapToDouble' und 'sum' (seit JDK 8.0): summe = (float) mitarbeiterliste.stream() .mapToDouble(ma -> ma.getGrundgehalt()) .sum(); /* --- oder mit Methodenreferenz: // summe = (float)mitarbeiterliste.stream() // .mapToDouble(Mitarbeiter::getGrundgehalt) // .sum(); /* ---------- for-each-Schleife (seit JDK 5.0): for (Mitarbeiter ma : mitarbeiterliste) { summe = summe + ma.getGrundgehalt(); } ---------- */ /* ---------- mit Iterator: Iterator iterMA = mitarbeiterliste.iterator(); while (iterMA.hasNext()) { Mitarbeiter ma = (Mitarbeiter) iterMA.next(); summe = summe + ma.getGrundgehalt(); } ---------- */ return summe; } // ------------------------------------------------------------------------- /** Berechnet die Gesamtkosten (= Personalkosten + Sachkosten). @return Gesamtkosten ohne Prämie */ public float gesamtkostenOhnePraemie() { return personalkostenOhnePraemie() + getSachkosten(); } // ------------------------------------------------------------------------- /** Berechnet die Prämie des Leiters der Organisation. @return Prämie */ public float praemie() { return gewinnOhnePraemie() * Manager.getGewinnanteil(); } // ------------------------------------------------------------------------- /** Berechnet die Personalkosten aus den Grundgehältern + Prämien der Mitarbeiter. @return Personalkosten + Prämien */ public float personalkosten() { return personalkostenOhnePraemie() + praemie(); } // ------------------------------------------------------------------------- /** Berechnet die Gesamtkosten (einschließlich der Prämien der Mitarbeiter). @return Gesamtkosten */ public float gesamtkosten() { return gesamtkostenOhnePraemie() + praemie(); } // ------------------------------------------------------------------------- /** Berechnet den Gewinn der Organisation (ohne Prämien der Mitarbeiter). @return Gewinn */ public float gewinn() { return gewinnOhnePraemie() - praemie(); } // ------------------------------------------------------------------------- /** Berechnet den Gewinn der Organisation (zur Bestimmung des Gewinnanteils). <br /> Dieser ist abhängig von der Art der Organisation (Abteilung oder Projekt). @see Abteilung#gewinnOhnePraemie() @see Projekt#gewinnOhnePraemie() @return Gewinn ohne Prämie */ public abstract float gewinnOhnePraemie(); }


Klasse Abteilung
/* * Abteilung.java */ package at.beringer.oopBuch.organisation; /** Instanzen dieser Klasse repräsentieren Abteilungen einer Organisation. <hr /> @since August 1999 @see Organisation @see OrganisationTesten @author Beringer Alfred */ public class Abteilung extends Organisation { // ------------------------------------------------------------------------- // Instanzattribute // ------------------------------------------------------------------------- private float einnahmen = 0.0f; // ------------------------------------------------------------------------- // Zugriffsmethoden (Get- und Set-Methoden) // ------------------------------------------------------------------------- /** Liefert die Einnahmen der Abteilung. @return Einnahmen */ public float getEinnahmen() { return einnahmen; } // ---------- /** Ändert die Einnahmen der Abteilung. @param einnahmen neue Einnahmen */ public void setEinnahmen(float einnahmen) { this.einnahmen = einnahmen; } // ------------------------------------------------------------------------- // Sonstige Instanzmethoden // ------------------------------------------------------------------------- /** Erhöht die Einnahmen der Abteilung. @param einnahmen Wert, der zu den Einnahmen addiert wird */ public void addiereZuEinnahmen(float einnahmen) { this.einnahmen += einnahmen; } // ------------------------------------------------------------------------- /** Berechnet den Gewinn der Abteilung. @see Organisation#gewinnOhnePraemie() @see Projekt#gewinnOhnePraemie() @return Einnahmen - Gesamtkosten ohne Prämie */ @Override public float gewinnOhnePraemie() { return getEinnahmen() - gesamtkostenOhnePraemie(); } }


Klasse Projekt
/* * Projekt.java */ package at.beringer.oopBuch.organisation; /** Instanzen dieser Klasse repräsentieren Projekte einer Organisation. <hr /> @since August 1999 @see Organisation @see OrganisationTesten @author Beringer Alfred */ public class Projekt extends Organisation { // ------------------------------------------------------------------------- // Instanzattribute // ------------------------------------------------------------------------- private int planZeit = 1; private float planJahresgewinn = 0.0f; private int planLebensdauer = 0; // ------------------------------------------------------------------------- // Zugriffsmethoden (Get- und Set-Methoden) // ------------------------------------------------------------------------- /** Liefert die geplante Zeit des Projekts in Jahren. @return Planzeit in Jahren */ public int getPlanZeit() { return planZeit; } // ---------- /** Ändert die geplante Zeit des Projekts. @param planZeit neue Planzeit in Jahren */ public void setPlanZeit(int planZeit) { this.planZeit = planZeit; } // ------------------------------------------------------------------------- /** Liefert den geplanten Jahresgewinn des Projekts. @return geplanter Jahresgewinn */ public float getPlanJahresgewinn() { return planJahresgewinn; } // ---------- /** Ändert den geplanten Jahresgewinn des Projekts. @param planJahresgewinn neuer geplanter Jahresgewinn des Projekts */ public void setPlanJahresgewinn(float planJahresgewinn) { this.planJahresgewinn = planJahresgewinn; } // ------------------------------------------------------------------------- /** Liefert die geplante Lebensdauer des Projekts in Jahren. @return geplante Lebensdauer in Jahren */ public int getPlanLebensdauer() { return planLebensdauer; } // ---------- /** Ändert die geplante Lebensdauer des Projekts. @param planLebensdauer neue Lebensdauer in Jahren */ public void setPlanLebensdauer(int planLebensdauer) { this.planLebensdauer = planLebensdauer; } // ------------------------------------------------------------------------- // Sonstige Instanzmethoden // ------------------------------------------------------------------------- /** Berechnet den Gewinn des Projekts. @see Organisation#gewinnOhnePraemie() @see Abteilung#gewinnOhnePraemie() @return Projektgewinn - Gesamtkosten ohne Prämie */ @Override public float gewinnOhnePraemie() { return (planJahresgewinn * planLebensdauer) / (planZeit * 12) - gesamtkostenOhnePraemie() ; } }


4.4.2 Klassendefinitionen - C#

Klasse Person
/* * Person.cs */ using System; using System.Text; namespace Beringer.oopBuch.Organisation { /** <summary> Jede Instanz dieser Klasse repräsentiert eine natürliche Person. <p> Seit: November 2004 </p> <seealso cref="Beringer.oopBuch.EinfacheBsp.Person1" /> <seealso cref="System.DateTime" /> <seealso cref="OrganisationMain" /> Autor: Beringer Alfred </summary> <remark> Zusätzlich wurde die 'ToString'-Methode implementiert. </remark> */ public class Person { // --------------------------------------------------------------------- // Klassenkonstante // --------------------------------------------------------------------- /** <summary> Kennzeichen für männliches Geschlecht. <br /> Wird im Klassenkonstruktor initialisiert (z.B. mit 'M'). </summary> */ public static readonly char MAENNLICH; /** <summary> Kennzeichen für weibliches Geschlecht. <br /> Wird im Klassenkonstruktor initialisiert (z.B. mit 'W'). </summary> */ public static readonly char WEIBLICH; /** <summary> Anrede für Personen männlichen Geschlechts. <br /> Wird im Klassenkonstruktor initialisiert (z.B. mit "Herr"). </summary> */ public static readonly String ANREDEMAENNLICH; /** <summary> Anrede für Personen weiblichen Geschlechts. <br /> Wird im Klassenkonstruktor initialisiert (z.B. mit "Frau"). </summary> */ public static readonly String ANREDEWEIBLICH; // --------------------------------------------------------------------- // Instanzattribute // --------------------------------------------------------------------- private String name; private DateTime geburtsdatum; private char geschlecht; private String adresse; // --------------------------------------------------------------------- // Klassenkonstruktor // --------------------------------------------------------------------- /** <summary> Klassenkonstruktor bzw. Klassen-Initialisierungsblock. </summary> <remarks> Die Werte für die nicht initialisierten Klassenkonstanten könnten von externen Datenquellen geholt werden, der Einfachheit halber werden die Werte jedoch fix vorgegeben. <dl> <dt>Hinweis: <dd>Nur in dieser Methode sind Zuweisungen für Klassenkonstanten erlaubt! </dl> </remarks> */ static Person() { MAENNLICH = 'M'; WEIBLICH = 'W'; ANREDEMAENNLICH = "Herr"; ANREDEWEIBLICH = "Frau"; } // --------------------------------------------------------------------- // Konstruktoren // --------------------------------------------------------------------- /** <summary> Eine Person muss mindestens ein Geburtsdatum und ein Geschlecht haben. Zusätzlich können der Name und die Adresse angegeben werden. <br /> Standardkonstruktor nicht erlaubt! <seealso cref="Person.Person(String, DateTime, char, String)" /> </summary> <param name="name"> Name </param> <param name="geburtsdatum"> Geburtsdatum </param> <param name="geschlecht"> Geschlecht </param> <param name="adresse"> Adresse </param> */ public Person(String name, DateTime geburtsdatum, char geschlecht, String adresse) { Name = name; setGeburtsdatum(geburtsdatum); setGeschlecht(geschlecht); Adresse = adresse; } /** <summary> Eine Person muss mindestens ein Geburtsdatum und ein Geschlecht haben. Zusätzlich kann der Name angegeben werden. <br /> Die Adresse wird mit einer leeren Zeichenkette initialisiert. <br /> Standardkonstruktor nicht erlaubt! <seealso cref="Person.Person(String, DateTime, char)" /> </summary> <param name="name"> Name </param> <param name="geburtsdatum"> Geburtsdatum </param> <param name="geschlecht"> Geschlecht </param> */ public Person(String name, DateTime geburtsdatum, char geschlecht) : this(name, geburtsdatum, geschlecht, "") { } /** <summary> Eine Person muss mindestens ein Geburtsdatum und ein Geschlecht haben. <br /> Name und Adresse werden mit einer leeren Zeichenkette initialisiert. <br /> Standardkonstruktor nicht erlaubt! <seealso cref="Person.Person(DateTime, char)" /> </summary> <param name="geburtsdatum"> Geburtsdatum </param> <param name="geschlecht"> Geschlecht </param> */ public Person(DateTime geburtsdatum, char geschlecht) : this("", geburtsdatum, geschlecht, "") { } // --------------------------------------------------------------------- // Properties // --------------------------------------------------------------------- /** <summary> Property für den Namen der Person. </summary> */ public String Name { get { return name; } set { name = value; } } /** <summary> Get-Property für das Geburtsdatum der Person. </summary> */ public DateTime Geburtsdatum { get { /* DateTime ist eine Struktur (d.h. ein Wertetyp), daher kann das Originalobjekt zurückgegeben werden. */ return geburtsdatum; } } /** <summary> Get-Property für das Geschlecht der Person. </summary> */ public char Geschlecht { get { return geschlecht; } } /** <summary> Property für die Adresse der Person. </summary> */ public String Adresse { get { return adresse; } set { adresse = value; } } // --------------------------------------------------------------------- // Öffentliche Instanzmethoden // --------------------------------------------------------------------- /** <summary> Liefert die Anrede für die Person. </summary> <returns> Anrede entsprechend dem Geschlecht bzw. leere Zeichenkette, falls das Geschlecht falsch ist </returns> */ virtual public String Anrede() { if (geschlecht == MAENNLICH) return ANREDEMAENNLICH; if (geschlecht == WEIBLICH) return ANREDEWEIBLICH; return ""; } /** <summary> Berechnet das Alter der Person. </summary> <returns> Alter in Jahren </returns> */ public int Alter() { DateTime heute = DateTime.Today; return heute.Year - geburtsdatum.Year; } // --------------------------------------------------------------------- // Methode 'ToString' // --------------------------------------------------------------------- /** <summary> Methode ToString (von Object) wird überschrieben. </summary> <remarks> String-Darstellung einer Personen-Instanz: <br /> Person[ Name = ..., Geschlecht = ..., Geburtsdatum = tt. mm. jj, Adresse = ... ] </remarks> <returns> String-Darstellung einer Personen-Instanz </returns> */ override public String ToString() { StringBuilder text = new StringBuilder(); DateTime datum = Geburtsdatum; // Zugriff auf Attribute nur über Properties (Datenkapselung)! text.Append( GetType().FullName).Append( "[ Name = ").Append(Name).Append( ", Geschlecht = ").Append(Geschlecht).Append( ", Geburtsdatum = ").Append( datum.Day).Append(". ").Append( datum.Month).Append(". ").Append( datum.Year).Append( ", Adresse = ").Append(Adresse).Append( " ]" ); return text.ToString(); } // --------------------------------------------------------------------- // Nichtöffentliche Zugriffsmethoden // --------------------------------------------------------------------- /** <summary> Ändert das Geburtsdatum der Person. </summary> <remarks> Das neue Geburtsdatum muss vor dem aktuellen Tagesdatum liegen. </remarks> <param name="value"> neues Geburtsdatum </param> <returns> true, wenn gültiges Geburtsdatum </returns> */ private bool setGeburtsdatum(DateTime value) { DateTime heute = DateTime.Today; if (value.CompareTo(heute) < 0) { /* DateTime ist eine Struktur (d.h. ein Wertetyp), daher kann das Parameterobjekt verwendet werden. */ this.geburtsdatum = value; return true; } // ungültiges Geburtsdatum this.geburtsdatum = heute; return false; } /** <summary> Ändert das Geschlecht der Person. </summary> <param name="value"> neues Geschlecht (männlich oder weiblich) </param> <returns> true, wenn gültiges Geschlecht </returns> */ private bool setGeschlecht(char value) { this.geschlecht = value; return ((value == MAENNLICH) || (value == WEIBLICH)) ? true : false; } } }


Klasse Kunde
/* * Kunde.cs */ using System; namespace Beringer.oopBuch.Organisation { /** <summary> Instanzen dieser Klasse repräsentieren Kunden. <p> Seit: November 2004 </p> <seealso cref="Person" /> Autor: Beringer Alfred </summary> */ public class Kunde : Person { // --------------------------------------------------------------------- // Instanzattribute // --------------------------------------------------------------------- private float jahresumsatz = 0.0f; private float kreditlimit = 0.0f; // --------------------------------------------------------------------- // Konstruktoren // --------------------------------------------------------------------- /** <summary> Konstruktor. <seealso cref="Person.Person(String, DateTime, char, String)" /> </summary> <param name="name"> Name </param> <param name="geburtsdatum"> Geburtsdatum </param> <param name="geschlecht"> Geschlecht </param> <param name="adresse"> Adresse </param> */ public Kunde(String name, DateTime geburtsdatum, char geschlecht, String adresse) : base(name, geburtsdatum, geschlecht, adresse) { } /** <summary> Konstruktor. <seealso cref="Person.Person(String, DateTime, char)" /> </summary> <param name="name"> Name </param> <param name="geburtsdatum"> Geburtsdatum </param> <param name="geschlecht"> Geschlecht </param> */ public Kunde(String name, DateTime geburtsdatum, char geschlecht) : this(name, geburtsdatum, geschlecht, "") { } /** <summary> Konstruktor. <seealso cref="Person.Person(DateTime, char)" /> </summary> <param name="geburtsdatum"> Geburtsdatum </param> <param name="geschlecht"> Geschlecht </param> */ public Kunde(DateTime geburtsdatum, char geschlecht) : this("", geburtsdatum, geschlecht, "") { } // --------------------------------------------------------------------- // Properties // --------------------------------------------------------------------- /** <summary> Property für den Jahresumsatz des Kunden. </summary> */ public float Jahresumsatz { get { return jahresumsatz; } set { jahresumsatz = value; } } /** <summary> Property für das Kreditlimit des Kunden. </summary> */ public float Kreditlimit { get { return kreditlimit; } set { kreditlimit = value; } } } }


Klasse Mitarbeiter
/* * Mitarbeiter.cs */ using System; using System.Reflection; namespace Beringer.oopBuch.Organisation { /** <summary> Instanzen dieser Klasse repräsentieren Mitarbeiter einer Organisation. <p> Seit: November 2004 </p> <seealso cref="Person" /> <seealso cref="Organisation" /> <seealso cref="OrganisationTesten" /> Autor: Beringer Alfred </summary> */ public class Mitarbeiter : Person { // --------------------------------------------------------------------- // Klassenattribute // --------------------------------------------------------------------- /** <summary> Klassenattribut für 'Mitarbeiter' und für alle 'Mitarbeiter'-Subklassen. </summary> */ private static int LetztePersNr = 0; /** <summary> Klassenattribut für Höchstgehalt, die für jede 'Mitarbeiter'-Subklasse unterschiedlich sein kann (entspricht somit einer Klasseninstanzvariablen). <seealso cref="Manager.MaxGehalt" /> </summary> */ private static float MaxGehalt; // --------------------------------------------------------------------- // Instanzattribute // --------------------------------------------------------------------- private int persNr; private String stellung = "Mitarbeiter"; private Organisation orga; protected float grundgehalt; // --------------------------------------------------------------------- // Klassenkonstruktor // --------------------------------------------------------------------- /** <summary> Klassen-Initialisierungsblock. </summary> <remarks> Der Wert für 'MaxGehalt' könnte auch aus einer externen Datenquelle (z.B. aus einer Datenbank) kommen. </remarks> */ static Mitarbeiter() { SetMaxGehalt(4500.0f); } // --------------------------------------------------------------------- // Konstruktoren // --------------------------------------------------------------------- /** <summary> Konstruktor. <seealso cref="Person.Person(String, DateTime, char, String)" /> </summary> <param name="name"> Name </param> <param name="geburtsdatum"> Geburtsdatum </param> <param name="geschlecht"> Geschlecht </param> <param name="adresse"> Adresse </param> */ public Mitarbeiter(String name, DateTime geburtsdatum, char geschlecht, String adresse) : base(name, geburtsdatum, geschlecht, adresse) { persNrNeu(); SetGrundgehalt(1200.0f); } /** <summary> Konstruktor. <seealso cref="Person.Person(String, DateTime, char)" /> </summary> <param name="name"> Name </param> <param name="geburtsdatum"> Geburtsdatum </param> <param name="geschlecht"> Geschlecht </param> */ public Mitarbeiter(String name, DateTime geburtsdatum, char geschlecht) : this(name, geburtsdatum, geschlecht, "") { } /** <summary> Konstruktor. <seealso cref="Person.Person(DateTime, char)" /> </summary> <param name="geburtsdatum"> Geburtsdatum </param> <param name="geschlecht"> Geschlecht </param> */ public Mitarbeiter(DateTime geburtsdatum, char geschlecht) : this("", geburtsdatum, geschlecht, "") { } // --------------------------------------------------------------------- // Properties // --------------------------------------------------------------------- /** <summary> Get-Property für die (eindeutige) Personalnummer des Mitarbeiters. </summary> */ public int PersNr { get { return persNr; } } /** <summary> Property für die Stellung (Position) des Mitarbeiters in der Organisation. </summary> */ public String Stellung { get { return stellung; } set { stellung = value; } } /** <summary> Get-Property für das Grundgehalt des Mitarbeiters. </summary> */ public float Grundgehalt { get { return grundgehalt; } } /** <summary> Property für die Organisation des Mitarbeiters. </summary> <remarks> Die Set-Methode ändert die Organisation des Mitarbeiters und fügt den Mitarbeiter in die neue Organisation ein, falls er dieser noch nicht angehört. </remarks> */ public Organisation Orga { get { return orga; } set { if (this.orga != null) { this.orga.RemoveMitarbeiter(this); } this.orga = value; if ( (this.orga != null) && !this.orga.Mitarbeiterliste.Contains(this)) { this.orga.AddMitarbeiter(this); } } } // --------------------------------------------------------------------- // Zugriffsmethoden // --------------------------------------------------------------------- /** <summary> Ändert das Grundgehalt des Mitarbeiters (soferne es nicht größer als das maximale Gehalt ist). </summary> <remarks> Diese Instanzmethode wird in jeder Subklasse identisch definiert (d.h. identisch überschrieben). </remarks> <param name="value"> neues Grundgehalt - darf nicht größer als das maximale Gehalt sein </param> <returns> true, wenn Grundgehalt geändert wird </returns> */ virtual public bool SetGrundgehalt(float value) { if (value <= Mitarbeiter.MaxGehalt) { this.grundgehalt = value; return true; } Console.WriteLine("Grundgehalt von " + this.GetType() + " kann maximal sein: " + MaxGehalt); return false; } // --------------------------------------------------------------------- // Instanzmethoden // --------------------------------------------------------------------- /** <summary> Liefert die Anrede des Mitarbeiters in der Organisation. <br /> Überschreibt die Methode 'Anrede' der Klasse 'Person'. <seealso cref="Person.Anrede()"/> </summary> <returns> Anrede entsprechend dem Geschlecht und der Stellung des Mitarbeiters </returns> */ override public String Anrede() { return base.Anrede() + " " + Stellung + " " + Name; } /** <summary> Liefert den Verdienst des Mitarbeiters (entspricht bei einfachen Mitarbeitern dem Grundgehalt). </summary> <returns> Verdienst </returns> */ virtual public float Verdient() { return Grundgehalt; } // --------------------------------------------------------------------- // Nichtöffentliche Methoden // --------------------------------------------------------------------- /** <summary> Ordnet jedem Mitarbeiter eine eindeutige (fortlaufende) Personalnummer zu. </summary> <returns> true, wenn Mitarbeiter noch keine Personalnummer hat </returns> */ private bool persNrNeu() { if (persNr == 0) { setLetztePersNr(getLetztePersNr() + 1); persNr = getLetztePersNr(); return true; } // Mitarbeiter hat bereits eine Personalnummer return false; } // --------------------------------------------------------------------- // Klassenmethoden // --------------------------------------------------------------------- /** <summary> Liefert die derzeit letzte Personalnummer aller Mitarbeiter. </summary> <returns> letzte zugeordnete Personalnummer </returns> */ protected static int getLetztePersNr() { return LetztePersNr; } /** <summary> Ändert die derzeit letzte Personalnummer aller Mitarbeiter. </summary> <param name="value"> neue letzte zugeordnete Personalnummer </param> */ private static void setLetztePersNr(int value) { Mitarbeiter.LetztePersNr = value; } /** <summary> Liefert das Höchstgehalt eines einfachen Mitarbeiters. </summary> <returns> Höchstgehalt </returns> */ public static float GetMaxGehalt() { return MaxGehalt; } /** <summary> Ändert die Höchstgrenze für das Grundgehalt eines einfachen Mitarbeiters. </summary> <param name="value"> neues Höchstgehalt </param> */ public static void SetMaxGehalt(float value) { Mitarbeiter.MaxGehalt = value; } } }


Klasse Manager
/* * Manager.cs */ using System; namespace Beringer.oopBuch.Organisation { /** <summary> Instanzen dieser Klasse repräsentieren Manager einer Organisation. <p> Seit: November 2004 </p> <seealso cref="Person" /> <seealso cref="Mitarbeiter" /> <seealso cref="Organisation" /> <seealso cref="OrganisationTesten" /> Autor: Beringer Alfred </summary> */ public class Manager : Mitarbeiter { // --------------------------------------------------------------------- // Klassenattribute // --------------------------------------------------------------------- /** <summary> Klasseninstanzvariable für Höchstgehalt (Klassenvariable aus der Klasse 'Mitarbeiter'). <seealso cref="Mitarbeiter.MaxGehalt" /> </summary> */ private static float MaxGehalt; /** <summary> Klassenvariable für Gewinnanteil. </summary> */ private static float Gewinnanteil = 0.05f; // --------------------------------------------------------------------- // Instanzattribute // --------------------------------------------------------------------- private Organisation geleiteteOrganisation; // --------------------------------------------------------------------- // Klassenkonstruktor // --------------------------------------------------------------------- /** <summary> Klassen-Initialisierungsblock. </summary> <remarks> Der Wert für 'MaxGehalt' könnte auch aus einer externen Datenquelle (z.B. aus einer Datenbank) kommen. <br /> Ebenso könnte auch 'Gewinnanteil' hier initialisiert werden. </remarks> */ static Manager() { SetMaxGehalt(15000.0f); } // --------------------------------------------------------------------- // Konstruktoren // --------------------------------------------------------------------- /** <summary> Konstruktor. <seealso cref="Person.Person(String, DateTime, char, String)" /> </summary> <param name="name"> Name </param> <param name="geburtsdatum"> Geburtsdatum </param> <param name="geschlecht"> Geschlecht </param> <param name="adresse"> Adresse </param> */ public Manager(String name, DateTime geburtsdatum, char geschlecht, String adresse) : base(name, geburtsdatum, geschlecht, adresse) { Stellung = "Leiter"; SetGrundgehalt(5000.0f); } /** <summary> Konstruktor. <seealso cref="Person.Person(String, DateTime, char)" /> </summary> <param name="name"> Name </param> <param name="geburtsdatum"> Geburtsdatum </param> <param name="geschlecht"> Geschlecht </param> */ public Manager(String name, DateTime geburtsdatum, char geschlecht) : this(name, geburtsdatum, geschlecht, "") { } /** <summary> Konstruktor. <seealso cref="Person.Person(DateTime, char)" /> </summary> <param name="geburtsdatum"> Geburtsdatum </param> <param name="geschlecht"> Geschlecht </param> */ public Manager(DateTime geburtsdatum, char geschlecht) : this("", geburtsdatum, geschlecht, "") { } // --------------------------------------------------------------------- // Properties // --------------------------------------------------------------------- /** <summary> Property für die vom Manager geleitete Organisation. </summary> <remarks> Die Set-Methode ändert die vom Manager geleitete Organisation, ändert gegebenenfalls auch seinen Status in der Organisation. </remarks> */ public Organisation GeleiteteOrganisation { get { return geleiteteOrganisation; } set { if (Orga != null) { Orga.RemoveMitarbeiter(this); } Orga = value; this.geleiteteOrganisation = value; if (value != null) { value.Leiter = this; } } } // --------------------------------------------------------------------- // Zugriffsmethoden // --------------------------------------------------------------------- /** <summary> Ändert das Grundgehalt des Managers (soferne es nicht größer als das maximale Gehalt ist). </summary> <remarks> Diese Instanzmethode wird in jeder Subklasse identisch definiert (d.h. identisch überschrieben). </remarks> <param name="value"> neues Grundgehalt - darf nicht größer als das maximale Gehalt sein </param> <returns> true, wenn Grundgehalt geändert wird </returns> */ override public bool SetGrundgehalt(float value) { if (value <= Manager.MaxGehalt) { this.grundgehalt = value; return true; } Console.WriteLine("Grundgehalt von " + this.GetType() + " kann maximal sein: " + MaxGehalt); return false; } // --------------------------------------------------------------------- // Sonstige Methoden // --------------------------------------------------------------------- /** <summary> Liefert den Verdienst des Managers (= Grundgehalt + Prämie). <br /> Überschreibt die Methode 'verdient' der Klasse Mitarbeiter. <seealso cref="Mitarbeiter.Verdient()" /> </summary> <returns> Verdienst </returns> */ override public float Verdient() { return Grundgehalt + (geleiteteOrganisation.GewinnOhnePraemie() * GetGewinnanteil()); } // --------------------------------------------------------------------- // Klassenmethoden // --------------------------------------------------------------------- /** <summary> Liefert das Höchstgehalt eines Managers. <seealso cref="Mitarbeiter.getMaxGehalt()" /> </summary> <remarks> Da die Klassen 'Manager' und 'Mitarbeiter' jeweils eigene Klassenvariablen 'MaxGehalt' haben, müssen auch in jeder Klasse eigene Zugriffsmethoden definiert werden. </remarks> <returns> Höchstgehalt </returns> */ new public static float GetMaxGehalt() { return Manager.MaxGehalt; } /** <summary> Ändert die Höchstgrenze für das Grundgehalt eines Managers. </summary> <param name="value"> neues Höchstgehalt </param> */ new public static void SetMaxGehalt(float value) { Manager.MaxGehalt = value; } /** <summary> Liefert den Gewinnanteil eines Managers. </summary> <returns> Gewinnanteil </returns> */ public static float GetGewinnanteil() { return Gewinnanteil; } /** <summary> Ändert den Gewinnanteil eines Managers. </summary> <param name="value"> neuer Gewinnanteil </param> */ public static void SetGewinnanteil(float value) { Gewinnanteil = value; } } }


Klasse Organisation
/* * Organisation.cs */ using System; using System.Collections; namespace Beringer.oopBuch.Organisation { /** <summary> Abstrakte Klasse für organisatorische Einheiten in einem Unternehmen.<br /> Solche organisatorischen Einheiten können Abteilungen, Projekte usw. sein. <p> Seit: November 2004 </p> <seealso cref="Mitarbeiter" /> <seealso cref="Manager" /> <seealso cref="Abteilung" /> <seealso cref="Projekt" /> <seealso cref="OrganisationTesten" /> Autor: Beringer Alfred </summary> */ public abstract class Organisation { // --------------------------------------------------------------------- // Instanzattribute // --------------------------------------------------------------------- private String name; private Manager leiter; private ArrayList mitarbeiterliste = new ArrayList(); private float sachkosten = 0.0f; // --------------------------------------------------------------------- // Properties // --------------------------------------------------------------------- /** <summary> Property für den Namen der Organisation. </summary> */ public String Name { get { return name; } set { name = value; } } /** <summary> Property für den Leiter der Organisation. </summary> */ public Manager Leiter { get { return leiter; } set { leiter = value; } } /** <summary> Property für die Sachkosten. </summary> */ public float Sachkosten { get { return sachkosten; } set { sachkosten = value; } } /** <summary> Get-Property für die Mitarbeiterliste der Organisation. </summary> */ public ArrayList Mitarbeiterliste { get { return mitarbeiterliste; } } // --------------------------------------------------------------------- // Zugriffsmethoden // --------------------------------------------------------------------- /** <summary> Fügt einen neuen Mitarbeiter hinzu; wird gegebenenfalls aus seiner vorhergehenden Organisation entfernt. </summary> <param name="einMitarbeiter"> neuer (hinzuzufügender) Mitarbeiter </param> */ public void AddMitarbeiter(Mitarbeiter einMitarbeiter) { Organisation bisherigeOrg = einMitarbeiter.Orga; if ( (bisherigeOrg != null) && (bisherigeOrg != this) ) { bisherigeOrg.RemoveMitarbeiter(einMitarbeiter); einMitarbeiter.Orga = this; } mitarbeiterliste.Add(einMitarbeiter); } /** <summary> Entfernt einen Mitarbeiter. </summary> <param name="einMitarbeiter"> zu entfernender Mitarbeiter </param> */ public void RemoveMitarbeiter(Mitarbeiter einMitarbeiter) { mitarbeiterliste.Remove(einMitarbeiter); } // --------------------------------------------------------------------- // Sonstige Methoden // --------------------------------------------------------------------- /** <summary> Erstellt eine Übersichtsliste aller Mitarbeiter + Leiter der Organisation. </summary> */ public void DruckeAlleMitarbeiter() { Console.WriteLine(this.GetType() + ": " + Name); if (leiter == null) Console.WriteLine("noch kein Manager als Leiter ernannt."); else Console.WriteLine("geleitet von: " + leiter.Name); Console.WriteLine("Anzahl Mitarbeiter = " + mitarbeiterliste.Count); foreach (Mitarbeiter ma in mitarbeiterliste) { Console.WriteLine(ma.Anrede() + " (Grundgehalt = " + ma.Grundgehalt + ")"); } } /** <summary> Erstellt eine Übersichtsliste der Gesamtkosten der Organisation. </summary> */ public void DruckeKostenUebersicht() { Console.WriteLine(this.GetType() + ": " + Name + " Kostenuebersicht"); Console.WriteLine( "---------------------------------------------------------------------------"); Console.WriteLine("Mitarbeiter \t\t\t Grundgehalt \t Verdienst"); Console.WriteLine( "---------------------------------------------------------------------------"); foreach (Mitarbeiter ma in mitarbeiterliste) { Console.WriteLine(ma.Anrede() + " \t\t " + ma.Grundgehalt + " \t " + ma.Verdient()); } Console.WriteLine( "---------------------------------------------------------------------------"); Console.WriteLine("Personalkosten = \t " + Personalkosten()); Console.WriteLine("Praemie = \t " + Praemie()); Console.WriteLine("Sachkosten = \t " + Sachkosten); Console.WriteLine("Gesamtkosten = \t " + Gesamtkosten()); Console.WriteLine("Gewinn = \t " + Gewinn()); } /** <summary> Berechnet die Personalkosten aus den Grundgehältern der Mitarbeiter. </summary> <returns> Personalkosten ohne Prämie </returns> */ public float PersonalkostenOhnePraemie() { float summe = 0.0f; foreach (Mitarbeiter ma in mitarbeiterliste) { summe = summe + ma.Grundgehalt; } return summe; } /** <summary> Berechnet die Gesamtkosten (= Personalkosten + Sachkosten). </summary> <returns> Gesamtkosten ohne Prämie </returns> */ public float GesamtkostenOhnePraemie() { return PersonalkostenOhnePraemie() + Sachkosten; } /** <summary> Berechnet die Prämie des Leiters der Organisation. </summary> <returns> Prämie </returns> */ public float Praemie() { return GewinnOhnePraemie() * Manager.GetGewinnanteil(); } /** <summary> Berechnet die Personalkosten aus den Grundgehältern + Prämien der Mitarbeiter. </summary> <returns> Personalkosten + Prämien </returns> */ public float Personalkosten() { return PersonalkostenOhnePraemie() + Praemie(); } /** <summary> Berechnet die Gesamtkosten (einschließlich der Prämien der Mitarbeiter). </summary> <returns> Gesamtkosten </returns> */ public float Gesamtkosten() { return GesamtkostenOhnePraemie() + Praemie(); } /** <summary> Berechnet den Gewinn der Organisation (ohne Prämien der Mitarbeiter). </summary> <returns> Gewinn </returns> */ public float Gewinn() { return GewinnOhnePraemie() - Praemie(); } /** <summary> Berechnet den Gewinn der Organisation (zur Bestimmung des Gewinnanteils). <br /> Dieser ist abhängig von der Art der Organisation (Abteilung oder Projekt). <seealso cref="Abteilung.GewinnOhnePraemie()"/> <seealso cref="Projekt.GewinnOhnePraemie()"/> </summary> <returns> Gewinn ohne Prämie </returns> */ public abstract float GewinnOhnePraemie(); } }


Klasse Abteilung
/* * Abteilung.cs */ namespace Beringer.oopBuch.Organisation { /** <summary> Instanzen dieser Klasse repräsentieren Abteilungen einer Organisation. <p> Seit: November 2004 </p> <seealso cref="Organisation" /> <seealso cref="OrganisationTesten" /> Autor: Beringer Alfred </summary> */ public class Abteilung : Organisation { // --------------------------------------------------------------------- // Instanzattribute // --------------------------------------------------------------------- private float einnahmen = 0.0f; // --------------------------------------------------------------------- // Properties // --------------------------------------------------------------------- /** <summary> Property für die Einnahmen der Abteilung. </summary> */ public float Einnahmen { get { return einnahmen; } set { einnahmen = value; } } // --------------------------------------------------------------------- // Instanzmethoden // --------------------------------------------------------------------- /** <summary> Erhöht die Einnahmen der Abteilung. </summary> <param name="einnahmen"> Wert, der zu den Einnahmen addiert wird </param> */ public void AddiereZuEinnahmen(float einnahmen) { this.einnahmen += einnahmen; } /** <summary> Berechnet den Gewinn der Abteilung. <seealso cref="Organisation.GewinnOhnePraemie()" /> <seealso cref="Projekt.GewinnOhnePraemie()" /> </summary> <returns> Einnahmen - Gesamtkosten ohne Prämie </returns> */ override public float GewinnOhnePraemie() { return Einnahmen - GesamtkostenOhnePraemie(); } } }


Klasse Projekt
/* * Projekt.cs */ namespace Beringer.oopBuch.Organisation { /** <summary> Instanzen dieser Klasse repräsentieren Projekte einer Organisation. <p> Seit: November 2004 </p> <seealso cref="Organisation" /> <seealso cref="OrganisationTesten" /> Autor: Beringer Alfred </summary> */ public class Projekt : Organisation { // --------------------------------------------------------------------- // Instanzattribute // --------------------------------------------------------------------- private int planZeit = 1; private float planJahresgewinn = 0.0f; private int planLebensdauer = 0; // --------------------------------------------------------------------- // Properties // --------------------------------------------------------------------- /** <summary> Property für die geplante Zeit des Projekts in Jahren. </summary> */ public int PlanZeit { get { return planZeit; } set { planZeit = value; } } /** <summary> Property für den geplanten Jahresgewinn des Projekts. </summary> */ public float PlanJahresgewinn { get { return planJahresgewinn; } set { planJahresgewinn = value; } } /** <summary> Property für die geplante Lebensdauer des Projekts in Jahren. </summary> */ public int PlanLebensdauer { get { return planLebensdauer; } set { planLebensdauer = value; } } // --------------------------------------------------------------------- // Instanzmethoden // --------------------------------------------------------------------- /** <summary> Berechnet den Gewinn des Projekts. <seealso cref="Organisation.GewinnOhnePraemie()" /> <seealso cref="Abteilung.GewinnOhnePraemie()" /> </summary> <returns> Projektgewinn - Gesamtkosten ohne Prämie </returns> */ override public float GewinnOhnePraemie() { return (planJahresgewinn * planLebensdauer) / (planZeit * 12) - GesamtkostenOhnePraemie() ; } } }


4.4.3 Klassendefinitionen - Smalltalk

Klasse Person
Smalltalk.BeringerOrganisation defineClass: #Person superclass: #{Core.Object} indexedType: #none private: false instanceVariableNames: 'name geburtsdatum geschlecht adresse ' classInstanceVariableNames: '' imports: '' category: 'Beispiel Organisation' Kommentar Jede Instanz dieser Klasse repräsentiert eine natürliche Person. Klassenvariable: MAENNLICH <Character> Kennzeichen männlich = M WEIBLICH <Character> Kennzeichen weiblich = W ANREDEMAENNLICH <String> Anrede männlich ANREDEWEIBLICH <String> Anrede weiblich Instanzvariable: name <String> vollständiger Name geburtsdatum <Date> Geburtsdatum geschlecht <Character> männlich oder weiblich adresse <String> vollständige Adresse
BeringerOrganisation.Person defineSharedVariable: #MAENNLICH private: false constant: true category: 'Klassenvariable' initializer: '$M' BeringerOrganisation.Person defineSharedVariable: #WEIBLICH private: false constant: true category: 'Klassenvariable' initializer: '$W' BeringerOrganisation.Person defineSharedVariable: #ANREDEMAENNLICH private: false constant: false category: 'Klassenvariable' initializer: nil BeringerOrganisation.Person defineSharedVariable: #ANREDEWEIBLICH private: false constant: false category: 'Klassenvariable' initializer: nil
BeringerOrganisation.Person   Klassenprotokoll   class initialization initialize ANREDEMAENNLICH := 'Herr'. ANREDEWEIBLICH := 'Frau'
BeringerOrganisation.Person   Klassenprotokoll   instance creation new "Eine Personeninstanz kann nur mit Geburtsdatum und Geschlecht erzeugt werden." self error: 'Keine Daten (mindestens Geburtsdatum und Geschlecht sind anzugeben)' newName: einName geburtsdatum: einDatum geschlecht: kennzGeschlecht adresse: eineAdresse "Anlegen einer Personeninstanz mit allen Attributen" ^ (super new) name: einName; geburtsdatum: einDatum; geschlecht: kennzGeschlecht; adresse: eineAdresse; initialize newName: einName geburtsdatum: einDatum geschlecht: kennzGeschlecht "Anlegen einer Personeninstanz mit Name, Geburtsdatum und Geschlecht" ^ self newName: einName geburtsdatum: einDatum geschlecht: kennzGeschlecht adresse: '' newGeburtsdatum: einDatum geschlecht: kennzGeschlecht "Anlegen einer Personeninstanz mit Geburtsdatum und Geschlecht" ^ self newName: '' geburtsdatum: einDatum geschlecht: kennzGeschlecht adresse: ''
BeringerOrganisation.Person   Protokoll   initialize-release initialize "Initialisiert eine neu erstellte Instanz. Kann in Subklassen überschrieben werden." super initialize. ^ self
BeringerOrganisation.Person   Protokoll   accessing name ^ name name: neuerName name := neuerName geburtsdatum ^ geburtsdatum copy "Achtung: nur eine Kopie des Originalobjekts wird zurückgegeben!" geschlecht ^ geschlecht adresse ^ adresse adresse: neueAdresse adresse := neueAdresse
BeringerOrganisation.Person   Protokoll   berechnungen anrede ( self geschlecht = MAENNLICH ) ifTrue: [ ^ ANREDEMAENNLICH ]. ( self geschlecht = WEIBLICH ) ifTrue: [ ^ ANREDEWEIBLICH ]. ^ '' alterBerechnen "liefert das Alter des Empfängers in Anzahl von Jahren (ohne Berücksichtigung des Monats)" ^ (Date today year - self geburtsdatum year)
BeringerOrganisation.Person   Protokoll   private geburtsdatum: einDatum ( (einDatum class == Date) and: [einDatum < Date today] ) ifTrue: [ geburtsdatum := einDatum copy. "Achtung: nur Kopie des Parameterobjekts verwenden!" ^ true ]. "ungültiges Geburtsdatum" geburtsdatum := Date today. ^ false geschlecht: kennzeichen geschlecht := kennzeichen. ( (kennzeichen = MAENNLICH) or: [kennzeichen = WEIBLICH] ) ifTrue: [ ^ true ]. "ungültiges Kennzeichen für Geschlecht" ^ false
<initialize> BeringerOrganisation.Person </initialize>


Klasse Kunde
Smalltalk.BeringerOrganisation defineClass: #Kunde superclass: #{BEorganisation.Person} indexedType: #none private: false instanceVariableNames: 'jahresumsatz kreditlimit ' classInstanceVariableNames: '' imports: '' category: 'Beispiel Organisation' Kommentar Instanzen dieser Klasse repräsentieren Kunden.
BeringerOrganisation.Kunde   Protokoll   initialize-release initialize super initialize. self jahresumsatz: 0. self kreditlimit: 0. ^ self
BeringerOrganisation.Kunde   Protokoll   accessing jahresumsatz ^ jahresumsatz jahresumsatz: eineZahl jahresumsatz := eineZahl kreditlimit ^ kreditlimit kreditlimit: eineZahl kreditlimit := eineZahl


Klasse Mitarbeiter
Smalltalk.BeringerOrganisation defineClass: #Mitarbeiter superclass: #{BEorganisation.Person} indexedType: #none private: false instanceVariableNames: 'persNr stellung grundgehalt organisation ' classInstanceVariableNames: 'MaxGehalt ' imports: '' category: 'Beispiel Organisation' Kommentar Jede Instanz dieser Klasse repräsentiert einen Mitarbeiter. Klasseninstanzvariable: MaxGehalt <Float> monatliches Maximalgehalt ohne Zuschläge Klassenvariable: LetztePersNr <Integer> zuletzt zugeteilte Personalnummer Instanzvariable: persNr <Integer> unternehmensweit eindeutige Personalnummer stellung <String> Funktion bzw. Position, die ein Mitarbeiter im Unternehmen hat grundgehalt <Float> monatliches Gehalt ohne Zuschläge organisation <Organisation> Abteilung oder Projekt, in der bzw. in dem ein Mitarbeiter arbeitet
BeringerOrganisation.Mitarbeiter defineSharedVariable: #LetztePersNr private: true constant: false category: 'Klassenvariable' initializer: 0
BeringerOrganisation.Mitarbeiter   Klassenprotokoll   class initialization initialize "Initialisiert Klassenvariable bzw. Klasseninstanzvariable." Mitarbeiter letztePersNr: 0. Mitarbeiter maxGehalt: 4500
BeringerOrganisation.Mitarbeiter   Klassenprotokoll   accessing letztePersNr ^ LetztePersNr maxGehalt ^ MaxGehalt maxGehalt: eineZahl MaxGehalt := eineZahl
BeringerOrganisation.Mitarbeiter   Klassenprotokoll   private letztePersNr: eineZahl LetztePersNr := eineZahl
BeringerOrganisation.Mitarbeiter   Protokoll   initialize-release initialize super initialize. self persNrNeu; stellung: 'Mitarbeiter'; grundgehalt: 1200. organisation: nil. ^ self
BeringerOrganisation.Mitarbeiter   Protokoll   accessing persNr ^ persNr stellung ^ stellung stellung: neueStellung stellung := neueStellung grundgehalt ^ grundgehalt grundgehalt: eineZahl (eineZahl <= self class maxGehalt) ifTrue: [ grundgehalt := eineZahl. ^ true ]. self error: 'Grundgehalt von ' , self class name , ' kann maximal sein: ' , self class maxGehalt printString. ^ false organisation ^ organisation organisation: eineOrganisation (eineOrganisation isKindOf: Organisation) ifTrue: [ (self organisation notNil) ifTrue: [ self organisation removeMitarbeiter: self ]. organisation := eineOrganisation. organisation addMitarbeiter: self ] ifFalse: [ (eineOrganisation isNil) ifTrue: [ (self organisation) notNil ifTrue: [ self organisation removeMitarbeiter: self ]. organisation := eineOrganisation ] ifFalse: [ self error: eineOrganisation class name , 'ist keine gültige Organisation' ] ]
BeringerOrganisation.Mitarbeiter   Protokoll   berechnungen anrede ^ super anrede , ' ' , self stellung , ' ' , self name verdient ^ self grundgehalt
BeringerOrganisation.Mitarbeiter   Protokoll   private persNrNeu persNr isNil ifTrue: [ self class letztePersNr: (self class letztePersNr + 1). persNr := self class letztePersNr. ^ true ]. self error: ' Mitarbeiter hat bereits eine Personalnummer'. ^ false
BeringerOrganisation.Mitarbeiter initialize


Klasse Manager
Smalltalk.BeringerOrganisation defineClass: #Manager superclass: #{BeringerOrganisation.Mitarbeiter} indexedType: #none private: false instanceVariableNames: 'geleiteteOrganisation ' classInstanceVariableNames: 'Gewinnanteil ' imports: '' category: 'Beispiel Organisation' Kommentar Instanzen dieser Klasse repräsentieren Leiter von Abteilungen oder Projekten.
BeringerOrganisation.Manager   Klassenprotokoll   class initialization initialize "Initialisiert Klassenvariable bzw. Klasseninstanzvariable." Manager maxGehalt: 15000. Manager gewinnanteil: 0.05
BeringerOrganisation.Manager   Klassenprotokoll   accessing gewinnanteil ^ Gewinnanteil gewinnanteil: eineZahl Gewinnanteil := eineZahl
BeringerOrganisation.Manager   Protokoll   initialize-release initialize super initialize. self stellung: 'Leiter'; grundgehalt: 5000. ^ self
BeringerOrganisation.Manager   Protokoll   accessing geleiteteOrganisation ^ geleiteteOrganisation geleiteteOrganisation: eineOrganisation (eineOrganisation isKindOf: Organisation) ifTrue: [ self organisation: eineOrganisation. geleiteteOrganisation := eineOrganisation. geleiteteOrganisation leiter: self. ^ true ]. self error: eineOrganisation class name , 'ist ungültige Organisation'. ^ false
BeringerOrganisation.Manager   Protokoll   berechnungen verdient ^ self grundgehalt + (geleiteteOrganisation gewinnOhnePraemie * self class gewinnanteil)
BeringerOrganisation.Manager initialize


Klasse Organisation
Smalltalk.BeringerOrganisation defineClass: #Organisation superclass: #{Core.Object} indexedType: #none private: false instanceVariableNames: 'name leiter mitarbeiterliste sachkosten ' classInstanceVariableNames: '' imports: '' category: 'Beispiel Organisation' Kommentar Abstrakte Klasse für organisatorische Einheiten in einem Unternehmen. Organisatorische Einheiten können Abteilungen, Projekte usw. sein.
BeringerOrganisation.Organisation   Protokoll   initialize-release initialize super initialize. mitarbeiterliste := Set new. self sachkosten: 0. ^ self
BeringerOrganisation.Organisation   Protokoll   accessing name ^ name name: neuerName name := neuerName leiter ^ leiter leiter: einManager leiter := einManager sachkosten ^ sachkosten sachkosten: eineZahl sachkosten := eineZahl mitarbeiterliste ^ mitarbeiterliste addMitarbeiter: einMitarbeiter | bisherigeOrg | bisherigeOrg := einMitarbeiter organisation. (bisherigeOrg ~= self) ifTrue: [ (bisherigeOrg notNil) ifTrue: [ bisherigeOrg removeMitarbeiter: einMitarbeiter ]. einMitarbeiter organisation: self ]. mitarbeiterliste add: einMitarbeiter removeMitarbeiter: einMitarbeiter mitarbeiterliste remove: einMitarbeiter ifAbsent: [ Transcript cr; show: 'Mitarbeiter wurde bereits entfernt' ]
BeringerOrganisation.Organisation   Protokoll   berechnungen gewinnOhnePraemie "Abstrakte Methode. Berechnet den Gewinn der Organisation (zur Bestimmung des Gewinnanteils). Dieser ist abhängig von der Art der Organisation (Abteilung oder Projekt)." self subclassResponsibility personalkostenOhnePraemie "Berechnet die Personalkosten aus den Grundgehältern der Mitarbeiter" | summe | summe := 0. mitarbeiterliste do: [ :ma | summe := summe + ma grundgehalt ]. ^ summe gesamtkostenOhnePraemie "Berechnet die Gesamtkosten (= Personalkosten + Sachkosten)." ^ self personalkostenOhnePraemie + self sachkosten praemie "Berechnet die Prämie des Leiters bzw. der Leiterin der Organisation" ^ self gewinnOhnePraemie * Manager gewinnanteil personalkosten "Berechnet die Personalkosten aus den Grundgehältern + Prämie des Managers" ^ self personalkostenOhnePraemie + self praemie gesamtkosten "Berechnet die Gesamtkosten (einschließlich der Prämien der Manager)." ^ self gesamtkostenOhnePraemie + self praemie gewinn "Berechnet den Gewinn der Organisation (ohne Prämien der Manager)." ^ self gewinnOhnePraemie - self praemie
BeringerOrganisation.Organisation   Protokoll   printing druckeAlleMitarbeiter "Erstellt eine Übersichtsliste aller Mitarbeiter + Leiter der Organisation." Transcript cr; show: self class name , ': ' , self name. (self leiter isNil) ifTrue: [ Transcript cr; show: 'noch kein Leiter ernannt.' ] ifFalse: [ Transcript cr; show: 'geleitet von: ' , self leiter name ]. Transcript cr; show: 'Anzahl Mitarbeiter = ' , mitarbeiterliste size printString. mitarbeiterliste do: [ :ma | Transcript cr; show: ma anrede , ' (Grundgehalt = ' , ma grundgehalt printString , ')' ] druckeKostenUebersicht "Erstellt eine Übersichtsliste der Gesamtkosten der Organisation." Transcript cr; show: self class name , ': ' , self name , ' Kostenübersicht' ; cr; show: '------------------------------------------------------------'. Transcript cr; show: 'Mitarbeiter' ; tab; tab; tab; tab; show: 'Grundgehalt' ; tab; show: 'Verdienst' ; cr; show: '------------------------------------------------------------'. mitarbeiterliste do: [ :ma | Transcript cr; show: ma anrede; tab; tab; show: ma grundgehalt printString; tab; show: ma verdient printString ]. Transcript cr; show: '------------------------------------------------------------'; cr; show: 'Personalkosten = '; tab; show: self personalkosten printString; cr; show: 'Prämie = '; tab; show: self praemie printString; cr; show: 'Sachkosten = '; tab; show: self sachkosten printString; cr; show: 'Gesamtkosten = '; tab; show: self gesamtkosten printString; cr; show: 'Gewinn = '; tab; show: self gewinn printString


Klasse Abteilung
Smalltalk.BeringerOrganisation defineClass: #Abteilung superclass: #{BeringerOrganisation.Organisation} indexedType: #none private: false instanceVariableNames: 'einnahmen ' classInstanceVariableNames: '' imports: '' category: 'Beispiel Organisation' Kommentar Instanzen repräsentieren Abteilungen (als spezielle organisatorische Einheiten) in einem Unternehmen.
BeringerOrganisation.Abteilung   Klassenprotokoll   instance creation new ^ super new initialize
BeringerOrganisation.Abteilung   Protokoll   initialize-release initialize super initialize. self einnahmen: 0. ^ self
BeringerOrganisation.Abteilung   Protokoll   accessing einnahmen ^ einnahmen
BeringerOrganisation.Abteilung   Protokoll   private einnahmen: eineZahl "Simuliert Setzen der Einnahmen (diese Set-Methode dient nur zum Testen - Einnahmen ergeben sich ja nur aus anderen Methoden wie überweisen, verkaufen o.ä)" einnahmen := eineZahl
BeringerOrganisation.Abteilung   Protokoll   berechnungen addiereZuEinnahmen: eineZahl "Einnahmen werden erhöht" self einnahmen: self einnahmen + eineZahl gewinnOhnePraemie "Liefert den Bruttogewinn des Empfängers" ^ self einnahmen - self gesamtkostenOhnePraemie


Klasse Projekt
Smalltalk.BeringerOrganisation defineClass: #Projekt superclass: #{BeringerOrganisation.Organisation} indexedType: #none private: false instanceVariableNames: 'planZeit planJahresgewinn planLebensdauer ' classInstanceVariableNames: '' imports: '' category: 'Beispiel Organisation' Kommentar Instanzen repräsentieren Projekte (als spezielle organisatorische Einheiten) in einem Unternehmen. BeringerOrganisation.Projekt   Klassenprotokoll   instance creation new ^ super new initialize
BeringerOrganisation.Projekt   Protokoll   initialize-release initialize super initialize. self planZeit: 1; planJahresgewinn: 0; planLebensdauer: 0. ^ self
BeringerOrganisation.Projekt   Protokoll   accessing planZeit ^ planZeit planZeit: anzahlJahre planZeit := anzahlJahre planJahresgewinn ^ planJahresgewinn planJahresgewinn: eineZahl planJahresgewinn := eineZahl planLebensdauer ^ planLebensdauer planLebensdauer: anzahlJahre planLebensdauer := anzahlJahre
BeringerOrganisation.Projekt   Protokoll   berechnungen gewinnOhnePraemie "Liefert den Bruttogewinn des Empfängers (pro Monat)" ^ (planJahresgewinn * planLebensdauer) / (planZeit * 12) – self gesamtkostenOhnePraemie


4.4.4 Anwendungsprogramm in Java, C# und Smalltalk

Anstelle einer Eingabe werden der Einfachheit halber konstante Werte für die Attribute vorgegeben.

Java - Testklasse

Klasse OrganisationTesten
/* * OrganisationTesten.java */ package at.beringer.oopBuch.organisation; import java.time.LocalDate; /** Applikation zum Testen des Beispiels "Personen - Mitarbeiter - Organisationen" (Buch Kap.4.4). <p> Die Testdaten werden der Einfachheit halber statisch vordefiniert. Es gibt keine Eingabedaten! </p> <hr /> @since August 1999 @version Jänner 2002 (Eurowerte) @version <br />August 2007 (eigene Programmklasse) @version <br />April 2014 (aktualisieren Java 8 - 'GregorianCalendar' ersetzen) @see Person @see Mitarbeiter @see Manager @see Organisation @see Abteilung @see Projekt @see ProgrammOrganisationTesten @author Beringer Alfred */ public class OrganisationTesten { // ------------------------------------------------------------------------- // Instanzmethoden // ------------------------------------------------------------------------- /** Start-Methode zum Testen der Applikation */ public void start() { Mitarbeiter mita11, mita12, mita2, mitp1, mitp21, mitp22; Manager mana1, mana2, manp1, manp2; Abteilung abt1, abt2; Projekt proj1, proj2; abt1 = new Abteilung(); abt1.setName("Abt1"); abt1.setEinnahmen(200000.0f); abt1.setSachkosten(7000.0f); abt2 = new Abteilung(); abt2.setName("Abt2"); abt2.setEinnahmen(350000.0f); proj1 = new Projekt(); proj1.setName("Projekt1"); proj2 = new Projekt(); proj2.setName("Projekt2"); proj2.setSachkosten(5500.0f); proj2.setPlanZeit(2); proj2.setPlanJahresgewinn(600000.0f); proj2.setPlanLebensdauer(6); // mita11 = new Mitarbeiter(); ***error*** geht nicht" mita11 = new Mitarbeiter(LocalDate.of(1962, 7, 17), 'M'); mita11.setName("Huber Hans"); mita11.setGrundgehalt(2100.0f); mita11.setOrganisation(abt1); mita12 = new Mitarbeiter(LocalDate.of(1977, 1 ,13), 'W'); mita12.setName("Irene Gross"); mita12.setGrundgehalt(2500.0f); mita12.setOrganisation(abt1); mita2 = new Mitarbeiter("Karli", LocalDate.now(), 'M'); mita2.setOrganisation(abt2); mitp1 = new Mitarbeiter("Doris", LocalDate.now(), 'W'); mitp1.setOrganisation(proj1); mitp21 = new Mitarbeiter("Hansi", LocalDate.now(), 'M'); mitp21.setOrganisation(proj2); mitp22 = new Mitarbeiter("Helga", LocalDate.now(), 'W'); mitp22.setOrganisation(proj2); mana1 = new Manager("Klammer Franz", LocalDate.now(), 'M'); mana1.setGrundgehalt(5500.0f); mana1.setOrganisation(abt1); mana1.setGeleiteteOrganisation(abt1); mana2 = new Manager("Muster Tom", LocalDate.now(), 'M'); mana2.setOrganisation(abt2); mana2.setGeleiteteOrganisation(abt2); manp1 = new Manager("Toni", LocalDate.now(), 'M'); manp1.setOrganisation(proj1); manp1.setGeleiteteOrganisation(proj1); manp2 = new Manager("Annemarie", LocalDate.now(), 'W'); manp2.setGrundgehalt(4700.0f); manp2.setOrganisation(proj2); manp2.setGeleiteteOrganisation(proj2); System.out.println("Personalnummern: " + mita11.getPersNr() + " " + mita12.getPersNr() + " " + mita2.getPersNr() + " " + mitp1.getPersNr() + " " + mitp21.getPersNr() + " " + mitp22.getPersNr() + " " + mana1.getPersNr() + " " + mana2.getPersNr() + " " + manp1.getPersNr() + " " + manp2.getPersNr()); System.out.println(mita12.anrede()); System.out.println(mana1.anrede()); System.out.println(mita11.alterBerechnen()); System.out.println(mita12.alterBerechnen()); System.out.println(mita11.verdient()); System.out.println(mana1.verdient()); System.out.println(manp2.verdient()); abt1.druckeAlleMitarbeiter(); System.out.println(); abt2.druckeAlleMitarbeiter(); System.out.println(); proj1.druckeAlleMitarbeiter(); System.out.println(); proj2.druckeAlleMitarbeiter(); System.out.println(); abt1.druckeKostenUebersicht(); System.out.println(); proj2.druckeKostenUebersicht(); System.out.println(); } }


Java - Programmklasse

Programmklasse ProgrammOrganisationTesten
/* * ProgrammOrganisationTesten.java */ package at.beringer.oopBuch.organisation; /** Programmklasse (Applikation) zum Testen des Beispiels "Personen - Mitarbeiter - Organisationen" (Buch Kap.4.4). <hr /> @since August 2007 @see OrganisationTesten @author Beringer Alfred */ public class ProgrammOrganisationTesten { // ------------------------------------------------------------------------- /** Der Einstiegspunkt für die Anwendung. @param args Kommandozeilenparameter */ public static void main(String[ ] args) { OrganisationTesten app = new OrganisationTesten(); app.start(); } }


C# - Testklasse

Klasse OrganisationTesten
/* * OrganisationTesten.cs */ using System; namespace Beringer.oopBuch.Organisation { /** <summary> Applikation zum Testen des Beispiels "Personen - Mitarbeiter - Organisationen" (Buch Kap.4.4). <p> Seit: November 2004 <br /> Version: August 2007 (eigene Programmklasse) </p> <seealso cref="Person" /> <seealso cref="Mitarbeiter" /> <seealso cref="Manager" /> <seealso cref="Organisation" /> <seealso cref="Abteilung" /> <seealso cref="Projekt" /> <seealso cref="ProgrammOrganisationTesten" /> Autor: Beringer Alfred </summary> <remarks> Die Testdaten werden der Einfachheit halber statisch vordefiniert. Es gibt keine Eingabedaten! </remarks> */ public class OrganisationTesten { /** -------------------------------------------------------------------- <summary> Start-Methode zum Testen der Applikation. </summary> */ public void Start() { Mitarbeiter mita11, mita12, mita2, mitp1, mitp21, mitp22; Manager mana1, mana2, manp1, manp2; Abteilung abt1, abt2; Projekt proj1, proj2; abt1 = new Abteilung(); abt1.Name = "Abt1"; abt1.Einnahmen = 200000.0f; abt1.Sachkosten = 7000.0f; abt2 = new Abteilung(); abt2.Name = "Abt2"; abt2.Einnahmen = 350000.0f; proj1 = new Projekt(); proj1.Name = "Projekt1"; proj2 = new Projekt(); proj2.Name = "Projekt2"; proj2.Sachkosten = 5500.0f; proj2.PlanZeit = 2; proj2.PlanJahresgewinn = 600000.0f; proj2.PlanLebensdauer = 6; // mita11 = new Mitarbeiter(); ***error*** geht nicht" mita11 = new Mitarbeiter(new DateTime(1962,7,17), 'M'); mita11.Name = "Huber Hans"; mita11.SetGrundgehalt(2100.0f); mita11.Orga = abt1; mita12 = new Mitarbeiter(new DateTime(1977,1,13), 'W'); mita12.Name = "Irene Gross"; mita12.SetGrundgehalt(2500.0f); mita12.Orga = abt1; mita2 = new Mitarbeiter("Karli", DateTime.Today, 'M'); mita2.Orga = abt2; mitp1 = new Mitarbeiter("Doris", DateTime.Today, 'W'); mitp1.Orga = proj1; mitp21 = new Mitarbeiter("Hansi", DateTime.Today, 'M'); mitp21.Orga = proj2; mitp22 = new Mitarbeiter("Helga", DateTime.Today, 'W'); mitp22.Orga = proj2; mana1 = new Manager("Klammer Franz", DateTime.Today, 'M'); mana1.SetGrundgehalt(5500.0f); mana1.Orga = abt1; mana1.GeleiteteOrganisation = abt1; mana2 = new Manager("Muster Tom", DateTime.Today, 'M'); mana2.Orga = abt2; mana2.GeleiteteOrganisation = abt2; manp1 = new Manager("Toni", DateTime.Today, 'M'); manp1.Orga = proj1; manp1.GeleiteteOrganisation = proj1; manp2 = new Manager("Annemarie", DateTime.Today, 'W'); manp2.SetGrundgehalt(4700.0f); manp2.Orga = proj2; manp2.GeleiteteOrganisation = proj2; Console.WriteLine( "Personalnummern: " + mita11.PersNr + " " + mita12.PersNr + " " + mita2.PersNr + " " + mitp1.PersNr + " " + mitp21.PersNr + " " + mitp22.PersNr + " " + mana1.PersNr + " " + mana2.PersNr + " " + manp1.PersNr + " " + manp2.PersNr ); Console.WriteLine(mita12.Anrede()); Console.WriteLine(mana1.Anrede()); Console.WriteLine(mita11.Alter()); Console.WriteLine(mita12.Alter()); Console.WriteLine(mita11.Verdient()); Console.WriteLine(mana1.Verdient()); Console.WriteLine(manp2.Verdient()); abt1.DruckeAlleMitarbeiter(); Console.WriteLine(); abt2.DruckeAlleMitarbeiter(); Console.WriteLine(); proj1.DruckeAlleMitarbeiter(); Console.WriteLine(); proj2.DruckeAlleMitarbeiter(); Console.WriteLine(); abt1.DruckeKostenUebersicht(); Console.WriteLine(); proj2.DruckeKostenUebersicht(); Console.WriteLine(); #if DEBUG Console.ReadLine(); #endif } } }


C# - Programmklasse

Programmklasse ProgrammOrganisationTesten
/* * ProgrammOrganisationTesten.cs */ using System; namespace Beringer.oopBuch.Organisation { /** <summary> Programmklasse (Applikation) zum Testen des Beispiels "Personen - Mitarbeiter - Organisationen" (Buch Kap.4.4). <p> Seit: August 2007 </p> <seealso cref="OrganisationTesten" /> Autor: Beringer Alfred </summary> */ public class ProgrammOrganisationTesten { /** -------------------------------------------------------------------- <summary> Der Haupteinstiegspunkt für die Anwendung. </summary> <param name="args"> Kommandozeilenparameter </param> */ public static void Main(String[] args) { OrganisationTesten app = new OrganisationTesten(); app.Start(); } } }


Smalltalk (Workspace)

Programm OrganisationProgramm
"Anwendungsprogramm für Beispiel Personen-Mitarbeiter-Organisation" | mita11 mita12 mita2 mitp1 mitp21 mitp22 mana1 mana2 manp1 manp2 abt1 abt2 proj1 proj2 | Mitarbeiter initialize. abt1 := Abteilung new. abt1 name: 'Abt1'; einnahmen: 200000; sachkosten: 7000. abt2 := Abteilung new. abt2 name: 'Abt2'; einnahmen: 350000. proj1 := Projekt new. proj1 name: 'Projekt1'. proj2 := Projekt new. proj2 name: 'Projekt2'; sachkosten: 5500; planZeit: 2; planJahresgewinn: 600000; planLebensdauer: 6. "mita11 := Mitarbeiter new. ***error*** geht nicht" mita11 := Mitarbeiter newGeburtsdatum: (Date readFromString:'07/17/1962') geschlecht: $M. mita11 name: 'Huber Hans'. mita11 grundgehalt: 2100; organisation: abt1. mita12 := Mitarbeiter newGeburtsdatum: (Date readFromString:'01/13/1977') geschlecht: $W. mita12 name: 'Irene Gross'. mita12 grundgehalt: 2500; organisation: abt1. mita2 := Mitarbeiter newName: 'Karli' geburtsdatum: (Date today) geschlecht: $M. mita2 organisation: abt2. mitp1 := Mitarbeiter newName: 'Doris' geburtsdatum: (Date today) geschlecht: $W. mitp1 organisation: proj1. mitp21 := Mitarbeiter newName: 'Hansi' geburtsdatum: (Date today) geschlecht: $M. mitp21 organisation: proj2. mitp22 := Mitarbeiter newName: 'Helga' geburtsdatum: (Date today) geschlecht: $W. mitp22 organisation: proj2. mana1 := Manager newName: 'Klammer Franz' geburtsdatum: (Date today) geschlecht: $M. mana1 grundgehalt: 5500; organisation: abt1; geleiteteOrganisation: abt1. mana2 := Manager newName: 'Muster Tom' geburtsdatum: (Date today) geschlecht: $M. mana2 organisation: abt2; geleiteteOrganisation: abt2. manp1 := Manager newName: 'Toni' geburtsdatum: (Date today) geschlecht: $M. manp1 organisation: proj1; geleiteteOrganisation: proj1. manp2 := Manager newName: 'Annemarie' geburtsdatum: (Date today) geschlecht: $W. manp2 grundgehalt: 4700; organisation: proj2; geleiteteOrganisation: proj2. Transcript clear; show: 'Personalnummern: ' , mita11 persNr printString , ' ' , mita12 persNr printString , ' ' , mita2 persNr printString , ' ' , mitp1 persNr printString , ' ' , mitp21 persNr printString , ' ' , mitp22 persNr printString , ' ' , mana1 persNr printString , ' ' , mana2 persNr printString , ' ' , manp1 persNr printString , ' ' , manp2 persNr printString. Transcript cr; show: mita12 anrede printString. Transcript cr; show: mana1 anrede printString. Transcript cr; show: mita11 alter printString. Transcript cr; show: mita12 alter printString. Transcript cr; show: mita11 verdient printString. Transcript cr; show: mana1 verdient printString. Transcript cr; show: manp2 verdient printString. abt1 druckeAlleMitarbeiter. Transcript cr. abt2 druckeAlleMitarbeiter. Transcript cr. proj1 druckeAlleMitarbeiter. Transcript cr. proj2 druckeAlleMitarbeiter. Transcript cr. abt1 druckeKostenUebersicht. Transcript cr. proj2 druckeKostenUebersicht. Transcript cr.


Jedes Programm bewirkt die folgende Ausgabe (aufgrund der Verwendung von ungeordneten Collections ist die Reihenfolge der Mitarbeiterzeilen innerhalb einer Abteilung bzw. innerhalb eines Projekts abhängig von der Programmiersprache, die Zahlen wurden nicht explizit formatiert - deren Darstellung ist daher ebenfalls abhängig von der Programmiersprache):

Personalnummern: 1 2 3 4 5 6 7 8 9 10
Frau Mitarbeiter Irene Gross
Herr Leiter Klammer Franz
43
28
2100.0
14645.0
11570.0

Abteilung: Abt1
geleitet von: Klammer Franz
Anzahl Mitarbeiter = 3
Frau Mitarbeiter Irene Gross     (Grundgehalt = 2500.0)
Herr Mitarbeiter Huber Hans      (Grundgehalt = 2100.0)
Herr Leiter Klammer Franz        (Grundgehalt = 5500.0)

Abteilung: Abt2
geleitet von: Muster Tom
Anzahl Mitarbeiter = 2
Herr Mitarbeiter Karli           (Grundgehalt = 1200.0)
Herr Leiter Muster Tom           (Grundgehalt = 5000.0)

Projekt: Projekt1
geleitet von: Toni
Anzahl Mitarbeiter = 2
Frau Mitarbeiter Doris           (Grundgehalt = 1200.0)
Herr Leiter Toni                 (Grundgehalt = 5000.0)

Projekt: Projekt2
geleitet von: Annemarie
Anzahl Mitarbeiter = 3
Frau Leiter Annemarie            (Grundgehalt = 4700.0)
Herr Mitarbeiter Hansi           (Grundgehalt = 1200.0)
Frau Mitarbeiter Helga           (Grundgehalt = 1200.0)

Abteilung: Abt1   Kostenübersicht
---------------------------------------------------------------------------
Mitarbeiter                         Grundgehalt	Verdienst
---------------------------------------------------------------------------
Frau Mitarbeiter Irene Gross           2500.0     2500.0
Herr Mitarbeiter Huber Hans            2100.0     2100.0
Herr Leiter Klammer Franz              5500.0    14645.0
---------------------------------------------------------------------------
Personalkosten =    19245.0
Praemie =            9145.0
Sachkosten =         7000.0
Gesamtkosten =      26245.0
Gewinn =           173755.0

Projekt: Projekt2   Kostenübersicht
---------------------------------------------------------------------------
Mitarbeiter                         Grundgehalt	Verdienst
---------------------------------------------------------------------------
Frau Leiter Annemarie                  4700.0    11570.0
Herr Mitarbeiter Hansi                 1200.0     1200.0
Frau Mitarbeiter Helga                 1200.0     1200.0
---------------------------------------------------------------------------
Personalkosten =    13970.0
Praemie =            6870.0
Sachkosten =         5500.0
Gesamtkosten =      19470.0
Gewinn =           130530.0



Weiter
zu den Java-Klassenbeispielen von Kapitel 5.19.1 (Exceptions)
zu den Java-Klassenbeispielen von Kapitel 6 (Ein-/Ausgabe von Daten)
zu den Java-Klassenbeispielen von Kapitel 7 (GUI)
zu Kapitel 8 (JDBC)
zu den C#-Klassenbeispielen von Kapitel 9.19.1 (Exceptions)
zu den C#-Klassenbeispielen von Kapitel 10 (Ein-/Ausgabe von Daten)
zu Kapitel 12 (PL/I)
zu Kapitel 13 (Reservierte Worte)
Zurück
zum Anfang dieses Kapitels
zum Inhaltsverzeichnis
 
zu Kapitel 1
zu den Klassenbeispielen von Kapitel 2
zur Parameterübergabe (Kapitel 2.7.1)
zu Kapitel 3
Zur
Java-Dokumentation der Java-Beispiele