2.5 Klassenbeispiele
Die folgenden Beispiele sind Übersetzungen der Klassendiagramme von Kap.2.3.3. Die Text-Hervorhebungen (Fettdruck, Schriftgröße usw.) dienen nur der optischen Aufbereitung und haben keinerlei syntaktische Bedeutung!
In der Klasse Person
werden beispielhaft Dokumenationskommentare definiert.
- Zu den Java-Klassen
- Zaehler
- Zaehler2
- Person
- Auto
- Datum
- Zaehler2
- Zu den C#-Klassen
- Zaehler
- Zaehler2
- Person
- Auto
- Datum
- Zaehler2
- Zu den Smalltalk-Klasse
- Zaehler
- Zaehler2
- Person
- Auto
- Datum
- Zaehler2
2.5.1 Java
Klasse Zaehler |
---|
/* * Zaehler.java */ package at.beringer.oopBuch.einfacheBsp; /** Instanzen dieser Klasse repräsentieren einen einfachen Zähler, der (um 1) erhöht und (auf 0) zurückgesetzt werden kann. <p> Anwendungsbeispiel: <pre> Zaehler z; z = new Zaehler(); z.erhoehen(); System.out.println(z.getWert()); </pre> </p> <hr /> @since August 1999 @version April 2002 (protected setWert) @see ProgrammZaehler @see Zaehler2 @see Zaehler3 @author Beringer Alfred */ public class Zaehler { // ------------------------------------------------------------------------- // Instanzattribute // ------------------------------------------------------------------------- private int wert; // ------------------------------------------------------------------------- // Konstruktoren // ------------------------------------------------------------------------- /** Standardkonstruktor. <p> Zähler wird zurückgesetzt. </p> */ public Zaehler() { reset(); } // ------------------------------------------------------------------------- // Öffentliche Zugriffsmethoden (Get- und Set-Methoden) // ------------------------------------------------------------------------- /** Liefert den aktuellen Wert des Zählers. @return aktueller Zählerwert */ public int getWert() { return wert; } // ------------------------------------------------------------------------- // Sonstige Öffentliche Instanzmethoden // ------------------------------------------------------------------------- /** Erhöht den Zähler um 1. @return neuer (inkrementierter) Zählerwert */ public int erhoehen() { setWert( getWert() + 1 ); return getWert(); /* Einfacher, aber mit weniger Kapselung: wert = wert + 1; return wert; */ } // ------------------------------------------------------------------------- /** Setzt den Zähler zurück auf 0. */ public void reset() { setWert(0); /* Einfacher, aber mit weniger Kapselung: wert = 0; */ } // ------------------------------------------------------------------------- // Nichtöffentliche Zugriffsmethoden // ------------------------------------------------------------------------- /** Ändert den Wert des Zählers - es erfolgt jedoch keine Prüfung auf Plausibilität! <p> Bem.: Die Zugriffsberechtigung wurde für die zusätzliche Beispielklasse 'Zaehler3' auf 'protected' geändert! </p> @param wert neuer (beliebiger) Zählerwert */ protected void setWert(int wert) { this.wert = wert; } } |
Klasse Zaehler2 |
---|
/* * Zaehler2.java */ package at.beringer.oopBuch.einfacheBsp; /** Instanzen dieser Klasse repräsentieren einen einfachen zweistelligen Zähler, der (um 1) erhöht und (auf 0) zurückgesetzt werden kann. <br /> Der Zähler beginnt nach 99 (= Standardwert für Endwert) wieder bei 0, d.h. bei 100 erfolgt ein Überlauf. <hr /> @since August 1999 @see ProgrammZaehler2 @see Zaehler @see Zaehler3 @author Beringer Alfred */ public class Zaehler2 { // ------------------------------------------------------------------------- // Klassenattribute // ------------------------------------------------------------------------- /** Der größte Wert, den der Zähler annehmen kann, danach muss der Zähler zurückgesetzt werden. */ private static int Endwert = 99; // ------------------------------------------------------------------------- // Instanzattribute // ------------------------------------------------------------------------- private int wert; // ------------------------------------------------------------------------- // Konstruktoren // ------------------------------------------------------------------------- /** Standardkonstruktor. <p> Zähler wird zurückgesetzt. </p> */ public Zaehler2() { reset(); } // ------------------------------------------------------------------------- // Öffentliche Zugriffsmethoden (Get- und Set-Methoden) // ------------------------------------------------------------------------- /** Liefert den aktuellen Wert des Zählers. @return aktueller Zählerwert */ public int getWert() { return wert; } // ------------------------------------------------------------------------- // Sonstige öffentliche Instanzmethoden // ------------------------------------------------------------------------- /** Erhöht den Zähler um 1 - bei Überlauf wird Zähler zurückgesetzt. @return neuer (inkrementierter) Zählerwert */ public int erhoehen() { setWert(getWert()+1); // Kapselung notwendig, um Überlauf zu erkennen! return getWert(); } // ------------------------------------------------------------------------- /** Setzt den Zähler zurück auf 0. */ public void reset() { setWert(0); } // ------------------------------------------------------------------------- // Nichtöffentliche Zugriffsmethoden // ------------------------------------------------------------------------- /** Ändert den Wert des Zählers. @param wert neuer Zählerwert, der zwischen 0 und Endwert liegen muss */ private void setWert(int wert) { this.wert = wert; if ((this.wert > Endwert) || (this.wert < 0)) { reset(); } } // ------------------------------------------------------------------------- // Klassenmethoden // ------------------------------------------------------------------------- /** Liefert den aktuellen Endwert für den Zähler. @return aktueller Endwert */ public static int getEndwert() { return Endwert; } // ---------- /** Definiert einen neuen Endwert für den Zähler - es erfolgt jedoch keine Prüfung auf Plausibilität! @param endwert neuer (beliebiger) Endwert */ public static void setEndwert(int endwert) { Endwert = endwert; } } |
Klasse Person |
---|
/* * Person.java */ package at.beringer.oopBuch.einfacheBsp; import java.time.LocalDate; /** Eine einfache Personen-Klasse. <p> Jede Instanz dieser Klasse repräsentiert eine natürliche Person. </p> <ul> <li>Klassenkonstante für gültige Geschlechtskennzeichen.</li> <li>Jede Person hat immer ein Geburtsjahr und ein Geschlecht.</li> <li>Geburtsjahr und Geschlecht können nicht geändert werden.</li> <li>Geburtsjahr und Geschlecht werden geprüft: <br /> Geburtsjahr darf nicht größer sein als das laufende Jahr, das Geschlecht darf nur 'M' oder 'W' sein.</li> </ul> <p> Hinweis: Die Namen der Standardzugriffsmethoden entsprechen NICHT den üblichen Java- bzw. UML-Konventionen ('getAttribut' bzw. 'setAttribut'). </p> <hr /> @since August 1999 @version Juli 2003 (Klassenkonstante für männlich und weiblich) @version <br />Juni 2006 (Geburtsjahr) @version <br />April 2014 (aktualisieren Java 8 - 'GregorianCalendar' ersetzen) @see Person7 @see at.beringer.oopBuch.organisation.Person @see Auto @author Beringer Alfred */ public class Person { // ------------------------------------------------------------------------- // Klassenkonstante // ------------------------------------------------------------------------- /** Kennzeichen für männliches Geschlecht. <p> Der Wert könnte von externen Datenquellen geholt werden, wird jedoch der Einfachheit halber fix vorgegeben. </p> */ public static final char MAENNLICH = 'M'; /** Kennzeichen für weibliches Geschlecht. <p> Der Wert könnte von externen Datenquellen geholt werden, wird jedoch der Einfachheit halber fix vorgegeben. </p> */ public static final char WEIBLICH = 'W'; // ------------------------------------------------------------------------- // Instanzattribute // ------------------------------------------------------------------------- private String vorname; private int geburtsjahr; private char geschlecht; // ------------------------------------------------------------------------- // Konstruktoren // ------------------------------------------------------------------------- /** Jede Person muss ein Geburtsjahr und ein Geschlecht haben. <p> Standardkonstruktor ist nicht erlaubt. </p> <p> Der Einfachheit halber wird bei falschen Werten keine Ausnahme geworfen. </p> @param geburtsjahr Geburtsjahr @param geschlecht Geschlecht */ public Person(int geburtsjahr, char geschlecht) { aendernGeburtsjahr(geburtsjahr); aendernGeschlecht(geschlecht); } // ------------------------------------------------------------------------- // Öffentliche Zugriffsmethoden (Get- und Set-Methoden) // ------------------------------------------------------------------------- /** Liefert den Vornamen der Person. @return Vorname */ public String heisst() { return vorname; } // ---------- /** Ändert den Vornamen der Person. @param neuerVorname neuer Vorname */ public void aendernVorname(String neuerVorname) { vorname = neuerVorname; } // ------------------------------------------------------------------------- /** Liefert das Geburtsjahr der Person. @return Geburtsjahr */ public int geboren() { return geburtsjahr; } // ------------------------------------------------------------------------- /** Liefert das Geschlecht der Person. @return Geschlecht */ public char hatGeschlecht() { return geschlecht; } // ------------------------------------------------------------------------- // Sonstige öffentliche Instanzmethoden // ------------------------------------------------------------------------- /** Liefert die Anrede für die Person (abhängig vom Geschlecht). <p> Die Anrede ist fix codiert und nicht variabel! </p> @return Anrede entsprechend dem Geschlecht */ public String anrede() { if (geschlecht == MAENNLICH) { return "Sehr geehrter Herr"; } return "Sehr geehrte Frau"; /* kürzer mit Bedingungsoperator: return (geschlecht == MAENNLICH) ? "Sehr geehrter Herr" : "Sehr geehrte Frau"; */ } // ------------------------------------------------------------------------- /** Berechnet das Alter der Person. @return Alter in Jahren */ public int alterBerechnen() { LocalDate heute = LocalDate.now(); return heute.getYear() - geburtsjahr; } // ------------------------------------------------------------------------- // Private Zugriffsmethoden // ------------------------------------------------------------------------- /** Setzt das Geburtsjahr der Person. <p> Das Geburtsjahr wird auf Gültigkeit geprüft: (Geburtsjahr <= laufendes Jahr). <br /> Bei einem Fehler wird das Geburtsjahr nicht gesetzt! </p> @param einJahr neues Geburtsjahr @return true, wenn 'einJahr' ein gültiges Geburtsjahr ist */ private boolean aendernGeburtsjahr(int einJahr) { int lfdJahr = LocalDate.now().getYear(); if (einJahr <= lfdJahr) { geburtsjahr = einJahr; return true; } // ungültiges Geburtsjahr return false; } // ------------------------------------------------------------------------- /** Setzt das Geschlecht der Person. <p> Das Geschlecht wird auf Gültigkeit geprüft. <br /> Bei einem Fehler wird das Geschlecht nicht gesetzt! </p> @param kennzeichen Kennzeichen für Geschlecht (männlich oder weiblich) @return true, wenn 'kennzeichen' ein gültiges Geschlechtskennzeichen ist */ private boolean aendernGeschlecht(char kennzeichen) { if ( (kennzeichen == MAENNLICH) || (kennzeichen == WEIBLICH) ) { geschlecht = kennzeichen; return true; } // ungültiges Kennzeichen für Geschlecht return false; } } |
Klasse Auto |
---|
/* * Auto.java */ package at.beringer.oopBuch.einfacheBsp; /** Eine sehr einfache Auto-Klasse, jede Instanz dieser Klasse repräsentiert ein Auto. <ul> <li>Jede Instanz wird mit einer Anfangsgeschwindigkeit von 10 km/h initialisiert.</li> <li>Rauf- und runterschalten bewirkt keine Geschwindigkeitsänderung.</li> <li>Bremsen und beschleunigen bewirkt immer eine Geschwindigkeitsänderung von 10%, jedoch keinen Gangwechsel.</li> </ul> <p> Es wurde zusätzlich noch (neben der Methode 'zeigeInhalt') die Methode 'toString' überschrieben. </p> <p> Diese Klasse dient auch als Fachobjekt ("model") für die GUI-Beispiele. </p> <hr /> @since Jänner 2002 @version Juli 2012 (PKW-Klasse umbenennen auf 'Auto'. Keine Initialisierung des Besitzers im Konstruktor.) @see Person @see AutoTesten @see ProgrammAutoTesten @see AutoM @author Beringer Alfred */ public class Auto { // ------------------------------------------------------------------------- // Klassenattribute // ------------------------------------------------------------------------- /** Mehrwertsteuersatz */ private static int MwstSatz; // ------------------------------------------------------------------------- // Instanzattribute // ------------------------------------------------------------------------- private String farbe; private int anzahlGaenge; private float geschwindigkeit; private int gang; private Person besitzer; // ------------------------------------------------------------------------- // Konstruktoren // ------------------------------------------------------------------------- /** Standardkonstruktor. <p> Alle Attribute (ausgenommen Besitzer) werden mit fixen Werten initialisiert. Es wird eine Anfangsgeschwindigkeit von 10 km/h angenommen. </p> */ public Auto() { setFarbe("rot"); setAnzahlGaenge(5); setGeschwindigkeit(10.0f); setGang(1); } // ------------------------------------------------------------------------- // Zugriffsmethoden (Get- und Set-Methoden) // ------------------------------------------------------------------------- /** Liefert die Farbe des Autos. @return Farbe */ public String getFarbe() { return farbe; } // ---------- /** Ändert die Farbe des Autos. @param farbe neue Farbe */ public void setFarbe(String farbe) { this.farbe = farbe; } // ------------------------------------------------------------------------- /** Liefert die Maximalanzahl der Gänge des Autos. @return Anzahl Gänge */ public int getAnzahlGaenge() { return anzahlGaenge; } // ---------- /** Ändert die Maximalanzahl der Gänge des Autos - dies entspricht einem Umbau des Autos. <ul> <li>Die Maximalanzahl der Gänge muss zumindest 1 sein.</li> <li>Der eingelegte Gang wird auf 1 zurückgesetzt.</li> </ul> @param anzahlGaenge neue Anzahl Gänge */ public void setAnzahlGaenge(int anzahlGaenge) { if (anzahlGaenge >= 1) { this.anzahlGaenge = anzahlGaenge; } setGang(1); } // ------------------------------------------------------------------------- /** Liefert die aktuelle Geschwindigkeit. @return Geschwindigkeit */ public float getGeschwindigkeit() { return geschwindigkeit; } // ---------- /** Ändert die aktuelle Geschwindigkeit. <p> Es erfolgt aber keine Prüfung auf Plausibilität! </p> @param geschwindigkeit neue Geschwindigkeit */ public void setGeschwindigkeit(float geschwindigkeit) { this.geschwindigkeit = geschwindigkeit; } // ------------------------------------------------------------------------- /** Liefert den gerade eingelegten Gang. @return Gang */ public int getGang() { return gang; } // ---------- /** Legt anderen Gang ein. <p> Der eingelegte Gang kann nicht kleiner sein als 1 und nicht höher als die Anzahl der Gänge. <br /> Bei einem Fehler wird der Gang nicht geändert. </p> @param gang neuer Gang */ public void setGang(int gang) { if ( (gang >= 1) && (gang <= anzahlGaenge) ) { this.gang = gang; } } // ------------------------------------------------------------------------- /** Liefert den Besitzer des Autos. @return Besitzer */ public Person getBesitzer() { return besitzer; } // ---------- /** Ändert den Besitzer des Autos. @param besitzer neuer Besitzer */ public void setBesitzer(Person besitzer) { this.besitzer = besitzer; } // ------------------------------------------------------------------------- // Sonstige Instanzmethoden // ------------------------------------------------------------------------- /** Gang um 1 erhöhen. */ public void raufschalten() { if (gang < anzahlGaenge) { gang = gang + 1; } } // ---------- /** Gang um 1 vermindern. */ public void runterschalten() { if (gang > 1) { gang = gang - 1; } } // ---------- /** Geschwindigkeit um 10% erhöhen. */ public void beschleunigen() { geschwindigkeit = geschwindigkeit * 1.1f; } // ---------- /** Geschwindigkeit um 10% vermindern. */ public void bremsen() { geschwindigkeit = geschwindigkeit * 0.9f; } // ------------------------------------------------------------------------- /** Schreibt alle Attribute in die Standardausgabe. <p> Achtung: Besitzer sollte bereits initialisiert sein! </p> <p> Anstelle dieser Methode sollte besser die Methode 'Object.toString()' überschrieben werden. </p> */ public void zeigeInhalt() { // direkter Zugriff auf Attribute (keine Datenkapselung) // 'getName()' liefert Pfad + Name der Klasse System.out.println(getClass().getName() + "-Daten: [ Mehrwertsteuersatz = " + MwstSatz + "%" ); System.out.println(" Besitzer = " + besitzer.heisst() + ", Farbe = " + farbe + ", Anzahl Gänge = " + anzahlGaenge ); System.out.println(" eingelegter Gang = " + gang + " / aktuelle Geschwindigkeit = " + geschwindigkeit + " ]" ); } // ------------------------------------------------------------------------- // Methode 'toString' // ------------------------------------------------------------------------- /** Überschreiben der Methode 'String Object.toString()'. <p> Achtung: Besitzer sollte bereits initialisiert sein! </p> <p> Liefert eine beschreibende Text-Darstellung einer Instanz der Klasse: <pre> Auto-Daten: [ Mehrwertsteuersatz = ...% Besitzer = ..., Farbe = ..., Anzahl Gänge = ... eingelegter Gang = ... / aktuelle Geschwindigkeit = ... ] </pre> </p> <p> Hinweis: Statt der Klasse 'String' sollte die Klasse 'StringBuilder' verwendet werden! </p> @see java.lang.Object#toString() @return Zeichenkette, die eine Instanz beschreibt */ @Override public String toString() { String neueZeile = System.getProperty("line.separator"); // Zugriff auf Attribute nur über Zugriffsmethoden (Datenkapselung) // 'getSimpleName()' liefert nur den Namen der Klasse return getClass().getSimpleName() + "-Daten: [ Mehrwertsteuersatz = " + getMwstSatz() + "%" + neueZeile + " Besitzer = " + getBesitzer().heisst() + ", Farbe = " + getFarbe() + ", Anzahl Gänge = " + getAnzahlGaenge() + neueZeile + " eingelegter Gang = " + getGang() + " / aktuelle Geschwindigkeit = " + getGeschwindigkeit() + " ]" ; } // ------------------------------------------------------------------------- // Klassenmethoden // ------------------------------------------------------------------------- /** Liefert den Mehrwertsteuersatz. @return Mehrwertsteuersatz */ public static int getMwstSatz() { return MwstSatz; } // ---------- /** Ändert den Mehrwertsteuersatz. @param mwstSatz neuer Mehrwertsteuersatz */ public static void setMwstSatz(int mwstSatz) { MwstSatz = mwstSatz; } } |
Klasse Datum |
---|
/* * Datum.java */ package at.beringer.oopBuch.einfacheBsp; import java.time.LocalDate; /** Eine einfache Datumsklasse. <p> Instanzen dieser Klasse können kopiert werden. </p> <hr /> @since August 1999 @version April 2002 (überschreiben 'Object.clone()') @version <br />April 2014 (aktualisieren Java 8 - 'GregorianCalendar' ersetzen) @see DatumTesten @see Datum7 @author Beringer Alfred */ public class Datum implements Cloneable { // ------------------------------------------------------------------------- // Klassenkonstante // ------------------------------------------------------------------------- private static final String[] Monatsnamen = { "Jänner ", "Februar ", "März ", "April ", "Mai ", "Juni ", "Juli ", "August ", "September", "Oktober ", "November ", "Dezember " }; private static final int[] TageProMonat = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; private static final int[] LfdTagMonatsanfang = { 1, 32, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 }; // ------------------------------------------------------------------------- // Instanzattribute // ------------------------------------------------------------------------- private int jj; private int mm; private int tt; // ------------------------------------------------------------------------- // Konstruktoren // ------------------------------------------------------------------------- /** Standardkonstruktor. <p> Initialisierung mit aktuellem Tagesdatum </p> */ public Datum() { LocalDate heute = LocalDate.now(); // liefert aktuelles Tagesdatum jj = heute.getYear(); mm = heute.getMonthValue(); tt = heute.getDayOfMonth(); } // ------------------------------------------------------------------------- /** Initialisierung mit einem beliebigen Tagesdatum. <p> Dieses Datum wird auf Gültigkeit geprüft, bei einem Fehler wird das aktuelle Tagesdatum zur Initialisierung verwendet. </p> @param jahr Jahr @param monat Monatsnummer (bei 1 (= Jänner) beginnend) @param tag Tag */ public Datum(int jahr, int monat, int tag) { this(); // initialisieren mit aktuellem Tagesdatum setDatum(jahr, monat, tag); } // ------------------------------------------------------------------------- // Zugriffsmethoden (Get- und Set-Methoden) // ------------------------------------------------------------------------- /** Liefert das Jahr. @return Jahr */ public int jj() { return jj; } // ---------- /** Liefert die Monatsnummer. @return Monatsnummer */ public int mm() { return mm; } // ---------- /** Liefert den Tag. @return Tag */ public int tt() { return tt; } // ------------------------------------------------------------------------- /** Liefert den Monatsnamen entsprechend der Monatsnummer. @return Monatsname */ public String monatsname() { return Monatsnamen[mm-1]; } // ------------------------------------------------------------------------- // Private Set-Methoden // ------------------------------------------------------------------------- /** Prüft und setzt ein korrektes Datum. <p> Der Einfachheit halber werden Fehlermeldungen auf die Konsole geschrieben. </p> @param jahr Jahr @param monat Monatsnummer @param tag Tag @return true, wenn das Datum korrekt ist */ private boolean setDatum(int jahr, int monat, int tag) { int tageProMonat; if (jahr == 0) { System.err.println("Fehler: " + jahr + " ist ungültig"); return false; } if ((monat < 1) || (monat > 12)) { System.err.println("Fehler: " + monat + " ist ungültig"); return false; } tageProMonat = TageProMonat[monat-1]; if ((monat == 2) && (Datum.istSchaltjahr(jahr))) { tageProMonat++; } if ((tag < 1) || (tag > tageProMonat)) { System.err.println("Fehler: " + tag + " ist ungültig"); return false; } jj = jahr; mm = monat; tt = tag; return true; } // ------------------------------------------------------------------------- // Sonstige Instanzmethoden // ------------------------------------------------------------------------- /** Liefert den laufenden Tag des Jahres. @return laufender Tag des Jahres */ public int lfdTagDesJahres() { int lfd; lfd = LfdTagMonatsanfang[mm-1] + tt - 1; if ( (mm > 2) && (this.istSchaltjahr()) ) { lfd++; } return lfd; } // ------------------------------------------------------------------------- /** Prüft das eigene Jahr auf Schaltjahr. @return true, wenn das eigene Jahr ein Schaltjahr ist */ public boolean istSchaltjahr() { return Datum.istSchaltjahr(jj); } // ------------------------------------------------------------------------- // Methoden 'toString' und 'clone' // ------------------------------------------------------------------------- /** Überschreiben der Methode 'String Object.toString()'. <p> Liefert eine beschreibende Text-Darstellung einer Instanz der Klasse: <pre> TT. MM. JJJJ </pre> </p> @see java.lang.Object#toString() @return Datum in der Form "TT. MM. JJJJ" */ @Override public String toString() { return tt + ". " + mm + ". " + jj; } // ------------------------------------------------------------------------- /** Überschreiben der Methode 'Object Object.clone()'. <p> Kopieren einer Datum-Instanz (tiefe Kopie): <ol> <li>Sichtbarkeit auf 'public' anheben ('Object.clone()' ist 'protected'!).</li> <li>Ausnahme 'CloneNotSupportedException' abfangen (auch wenn die Klasse 'Datum' die Kennzeichenschnittstelle 'Cloneable' bereits implementiert!).</li> <li>Vererbte Methode 'Object.clone()' aufrufen ('super.clone()').</li> <li>Veränderliche Attribute kopieren: <br /> Da diese Klasse keine veränderlichen Attribute hat, ist für eine tiefe Kopie nichts weiter zu tun. <br /> (Wenn bereits in Get-/Set-Methoden nur Kopien von veränderlichen Attributen verwendet werden, könnten diese Methoden für das Kopieren dieser Attribute verwendet werden.)</li> </ol> </p> @see java.lang.Object#clone() @return (tiefe) Kopie eines Datums */ @Override public Object clone() { Datum datumKopie; try { datumKopie = (Datum) super.clone(); /* hier folgt das Kopieren der veränderlichen Attribute (für eine tiefe Kopie) z.B.: kopie.setAttribut(getAttribut()); */ return datumKopie; } catch (CloneNotSupportedException e) { // zurückgeben eines Dummy-Wertes! return null; } } // ------------------------------------------------------------------------- // Klassenmethoden // ------------------------------------------------------------------------- /** Liefert das aktuelle Tagesdatum. @return Instanz des aktuellen Tagesdatums */ public static Datum heute() { return new Datum(); } // ------------------------------------------------------------------------- /** Prüft ein vorgegebenes Jahr auf Schaltjahr. @param jahr zu prüfende Jahreszahl @return true, wenn 'jahr' ein Schaltjahr ist */ public static boolean istSchaltjahr(int jahr) { return ((jahr%4 != 0) || ((jahr%100 == 0) && (jahr%400 != 0))) ? false : true; } } |
2.5.2 C#
Klasse Zaehler |
---|
/* * Zaehler.cs */ namespace Beringer.oopBuch.EinfacheBsp { /** <summary> Instanzen dieser Klasse repräsentieren einen einfachen Zähler, der (um 1) erhöht und (auf 0) zurückgesetzt werden kann. <example> Anwendungsbeispiel: <pre> Zaehler z; z = new Zaehler(); z.Erhoehen(); Console.WriteLine(z.Wert); </pre> </example> <p> Seit: November 2004 </p> <seealso cref="Beringer.oopBuch.EinfacheBspProgramme.ProgrammZaehler"/> <seealso cref="Zaehler2" /> <seealso cref="Zaehler3" /> Autor: Beringer Alfred </summary> */ public class Zaehler { // --------------------------------------------------------------------- // Instanzattribute // --------------------------------------------------------------------- private int wert; // --------------------------------------------------------------------- // Konstruktoren // --------------------------------------------------------------------- /** <summary> Standardkonstruktor. </summary> <remarks> Zähler wird zurückgesetzt. </remarks> */ public Zaehler() { Reset(); } // --------------------------------------------------------------------- // Properties // --------------------------------------------------------------------- /** <summary> Get-Property für den aktuellen Wert des Zählers. </summary> */ public int Wert { get { return wert; } } // --------------------------------------------------------------------- // Öffentliche Instanzmethoden // --------------------------------------------------------------------- /** <summary> Erhöht den Zähler um 1. </summary> <returns> neuer (inkrementierter) Zählerwert </returns> */ public int Erhoehen() { setWert( Wert + 1 ); return Wert; /* Einfacher, aber mit weniger Kapselung: wert = wert + 1; return wert; */ } // --------------------------------------------------------------------- /** <summary> Setzt den Zähler zurück auf 0. </summary> */ public void Reset() { setWert(0); /* Einfacher, aber mit weniger Kapselung: wert = 0; */ } // --------------------------------------------------------------------- // Nichtöffentliche Zugriffsmethoden // --------------------------------------------------------------------- /** <summary> Ändert den Wert des Zählers - es erfolgt jedoch keine Prüfung auf Plausibilität! </summary> <remarks> Die Zugriffsberechtigung wurde für die zusätzliche Beispielklasse Zaehler3 auf protected geändert! </remarks> <param name="value"> neuer (beliebiger) Zählerwert </param> */ virtual protected void setWert(int value) { this.wert = value; } } } |
Klasse Zaehler2 |
---|
/* * Zaehler2.cs */ namespace Beringer.oopBuch.EinfacheBsp { /** <summary> Instanzen dieser Klasse repräsentieren einen einfachen zweistelligen Zähler, der (um 1) erhöht und (auf 0) zurückgesetzt werden kann. <br /> Der Zähler beginnt nach 99 (= Standardwert für Endwert) wieder bei 0, d.h. bei 100 erfolgt ein Überlauf. <p> Seit: November 2004 </p> <seealso cref="Beringer.oopBuch.EinfacheBspProgramme.ProgrammZaehler2"/> <seealso cref="Zaehler" /> <seealso cref="Zaehler3" /> Autor: Beringer Alfred </summary> */ public class Zaehler2 { // --------------------------------------------------------------------- // Klassenattribute // --------------------------------------------------------------------- /** <summary> Der größte Wert, den der Zähler annehmen kann, danach muss der Zähler zurückgesetzt werden. </summary> */ private static int endwert = 99; // --------------------------------------------------------------------- // Instanzattribute // --------------------------------------------------------------------- private int wert; // --------------------------------------------------------------------- // Konstruktoren // --------------------------------------------------------------------- /** <summary> Standardkonstruktor. </summary> <remarks> Zähler wird zurückgesetzt </remarks> */ public Zaehler2() { Reset(); } // --------------------------------------------------------------------- // Properties // --------------------------------------------------------------------- /** <summary> Get-Property für den aktuellen Wert des Zählers. </summary> */ public int Wert { get { return wert; } } // --------------------------------------------------------------------- // Öffentliche Instanzmethoden // --------------------------------------------------------------------- /** <summary> Erhöht den Zähler um 1 - bei Überlauf wird Zähler zurückgesetzt. </summary> <returns> neuer (inkrementierter) Zählerwert </returns> */ public int Erhoehen() { setWert(Wert+1); // Kapselung notwendig, um Überlauf zu erkennen! return Wert; } // --------------------------------------------------------------------- /** <summary> Setzt den Zähler zurück auf 0. </summary> */ public void Reset() { setWert(0); } // --------------------------------------------------------------------- // Nichtöffentliche Zugriffsmethoden // --------------------------------------------------------------------- /** <summary> Ändert den Wert des Zählers. </summary> <param name="value"> neuer Zählerwert, der zwischen 0 und Endwert liegen muss </param> */ private void setWert(int value) { this.wert = value; if ((this.wert > endwert) || (this.wert < 0)) { Reset(); } } // --------------------------------------------------------------------- // Klassenmethoden // --------------------------------------------------------------------- /** <summary> Liefert den aktuellen Endwert für den Zähler. </summary> <returns> aktueller Endwert </returns> */ public static int Endwert() { return endwert; } // --------------------------------------------------------------------- /** <summary> Definiert einen neuen Endwert für den Zähler - es erfolgt jedoch keine Prüfung auf Plausibilität! </summary> <param name="value"> neuer (beliebiger) Endwert </param> */ public static void Endwert(int value) { endwert = value; } } } |
Klasse Person |
---|
/* * Person.cs */ using System; namespace Beringer.oopBuch.EinfacheBsp { /** <summary> Eine einfache Personen-Klasse. <p> Jede Instanz dieser Klasse repräsentiert eine natürliche Person. </p> <ul> <li>Klassenkonstante für gültige Geschlechtskennzeichen.</li> <li>Jede Person hat immer ein Geburtsjahr und ein Geschlecht.</li> <li>Geburtsjahr und Geschlecht können nicht geändert werden.</li> <li>Geburtsjahr und Geschlecht werden geprüft: <br /> Geburtsjahr darf nicht größer sein als das laufende Jahr, das Geschlecht darf nur 'M' oder 'W' sein.</li> </ul> <p> Seit: November 2004 <br /> Änderung: Juni 2006 (Geburtsjahr) </p> <seealso cref="Beringer.oopBuch.Organisation.Person" /> <seealso cref="Auto" /> Autor: Beringer Alfred </summary> <remarks> Die Standardzugriffsmethoden wurden NICHT als Properties definiert.<br /> Die Namen dieser Standardzugriffsmethoden entsprechen auch NICHT den üblichen UML-Konventionen ('getAttribut' bzw. 'setAttribut'). </remarks> */ public class Person { // --------------------------------------------------------------------- // Klassenkonstante // --------------------------------------------------------------------- /** <summary> Kennzeichen für männliches Geschlecht. </summary> <remarks> Der Wert könnte von externen Datenquellen geholt werden, wird jedoch der Einfachheit halber fix vorgegeben. </remarks> */ public static readonly char MAENNLICH = 'M'; /** <summary> Kennzeichen für weibliches Geschlecht. </summary> <remarks> Der Wert könnte von externen Datenquellen geholt werden, wird jedoch der Einfachheit halber fix vorgegeben. </remarks> */ public static readonly char WEIBLICH = 'W'; // --------------------------------------------------------------------- // Instanzattribute // --------------------------------------------------------------------- private String vorname; private int geburtsjahr; private char geschlecht; // --------------------------------------------------------------------- // Konstruktoren // --------------------------------------------------------------------- /** <summary> Jede Person muss ein Geburtsjahr und ein Geschlecht haben. </summary> <remarks> Standardkonstruktor ist nicht erlaubt. </remarks> <param name="geburtsjahr"> Geburtsjahr </param> <param name="geschlecht"> Geschlecht </param> */ public Person(int geburtsjahr, char geschlecht) { aendernGeburtsjahr(geburtsjahr); aendernGeschlecht(geschlecht); } // --------------------------------------------------------------------- // (Öffentliche) Zugriffsmethoden (Get- und Set-Methoden) // In C# sollten dies Properties sein! // --------------------------------------------------------------------- /** <summary> Liefert den Vornamen der Person. </summary> <returns> Vorname </returns> */ public String Heisst() { return vorname; } // ---------- /** <summary> Ändert den Vornamen der Person. </summary> <param name="neuerVorname"> neuer Vorname </param> */ public void AendernVorname(String neuerVorname) { vorname = neuerVorname; } // --------------------------------------------------------------------- /** <summary> Liefert das Geburtsjahr der Person. </summary> <returns> Geburtsjahr </returns> */ public int Geboren() { return geburtsjahr; } // --------------------------------------------------------------------- /** <summary> Liefert das Geschlecht der Person. </summary> <returns> Geschlecht </returns> */ public char HatGeschlecht() { return geschlecht; } // --------------------------------------------------------------------- // Sonstige Instanzmethoden // --------------------------------------------------------------------- /** <summary> Liefert die Anrede für die Person (abhängig vom Geschlecht). </summary> <remarks> Die Anrede ist fix codiert und nicht variabel! </remarks> <returns> Anrede entsprechend dem Geschlecht </returns> */ public String Anrede() { if (geschlecht == MAENNLICH) { return "Sehr geehrter Herr"; } return "Sehr geehrte Frau"; /* kürzer mit Bedingungsoperator: return (geschlecht == MAENNLICH) ? "Sehr geehrter Herr" : "Sehr geehrte Frau"; */ } // --------------------------------------------------------------------- /** <summary> Berechnet das Alter der Person. </summary> <returns> Alter in Jahren </returns> */ public int AlterBerechnen() { return DateTime.Today.Year - geburtsjahr; } // --------------------------------------------------------------------- // Nichtöffentliche Zugriffsmethoden // --------------------------------------------------------------------- /** <summary> Setzt das Geburtsjahr der Person. </summary> <remarks> Das Geburtsjahr wird auf Gültigkeit geprüft: (Geburtsjahr <= laufendes Jahr). <br /> Bei einem Fehler wird das Geburtsjahr nicht gesetzt! </remarks> <param name="einJahr"> neues Geburtsjahr </param> <returns> true, wenn 'einJahr' ein gültiges Geburtsjahr ist </returns> */ private bool aendernGeburtsjahr(int einJahr) { int lfdJahr = DateTime.Today.Year; if (einJahr <= lfdJahr) { geburtsjahr = einJahr; return true; } // ungültiges Geburtsjahr return false; } // --------------------------------------------------------------------- /** <summary> Setzt das Geschlecht der Person. </summary> <remarks> Das Geschlecht wird auf Gültigkeit geprüft. <br /> Bei einem Fehler wird das Geschlecht nicht gesetzt! </remarks> <param name="kennzeichen"> Kennzeichen für Geschlecht (männlich oder weiblich) </param> <returns> true, wenn 'kennzeichen' ein gültiges Geschlechtskennzeichen ist </returns> */ private bool aendernGeschlecht(char kennzeichen) { if ( (kennzeichen == MAENNLICH) || (kennzeichen == WEIBLICH) ) { geschlecht = kennzeichen; return true; } // ungültiges Kennzeichen für Geschlecht return false; } } } |
Klasse Auto |
---|
/* * Auto.cs */ using System; namespace Beringer.oopBuch.EinfacheBsp { /** <summary> Eine sehr einfache Auto-Klasse, jede Instanz dieser Klasse repräsentiert ein Auto. <ul> <li>Jede Instanz wird mit einer Anfangsgeschwindigkeit von 10 km/h initialisiert.</li> <li>Rauf- und runterschalten bewirkt keine Geschwindigkeitsänderung.</li> <li>Bremsen und beschleunigen bewirkt immer eine Geschwindigkeitsänderung von 10%, jedoch keinen Gangwechsel.</li> </ul> <p> Seit: November 2004 <br /> Version: Juli 2012 (PKW-Klasse umbenennen auf 'Auto'. Keine Initialisierung des Besitzers im Konstruktor.) </p> <seealso cref="Person" /> <seealso cref="AutoTesten" /> <seealso cref="Beringer.oopBuch.EinfacheBspProgramme.ProgrammAutoTesten"/> <seealso cref="AutoM" /> Autor: Beringer Alfred </summary> <remarks> Es wurde zusätzlich noch (neben der Methode 'ZeigeInhalt') die Methode 'ToString' überschrieben. <p> Diese Klasse dient auch als Fachobjekt ("model") für die GUI-Beispiele. </p> </remarks> */ public class Auto { // --------------------------------------------------------------------- // Klassenattribute // --------------------------------------------------------------------- /// <summary>Mehrwertsteuersatz</summary> private static int mwstSatz; // --------------------------------------------------------------------- // Instanzattribute // --------------------------------------------------------------------- private String farbe; private int anzahlGaenge; private float geschwindigkeit; private int gang; private Person besitzer; // --------------------------------------------------------------------- // Konstruktoren // --------------------------------------------------------------------- /** <summary> Standardkonstruktor. </summary> <remarks> Alle Attribute (ausgenommen Besitzer) werden mit fixen Werten initialisiert. Es wird eine Anfangsgeschwindigkeit von 10 km/h angenommen. </remarks> */ public Auto() { Farbe = "rot"; AnzahlGaenge = 5; Geschwindigkeit = 10.0f; Gang = 1; } // --------------------------------------------------------------------- // Properties // --------------------------------------------------------------------- /** <summary> Property für die Farbe des Autos. </summary> */ public String Farbe { get { return farbe; } set { farbe = value; } } // --------------------------------------------------------------------- /** <summary> Property für die Maximalanzahl der Gänge des Autos. </summary> <remarks> Die Änderung der Maximalanzahl der Gänge des Autos entspricht einem Umbau des Autos. <p> Set-Property: <ul> <li>Die Maximalanzahl der Gänge muss zumindest 1 sein.</li> <li>Der eingelegte Gang wird auf 1 zurückgesetzt.</li> </ul> </p> </remarks> */ public int AnzahlGaenge { get { return anzahlGaenge; } set { if (value >= 1) { anzahlGaenge = value; } Gang = 1; } } // --------------------------------------------------------------------- /** <summary> Property für die aktuelle Geschwindigkeit. </summary> <remarks> Set-Methode: Es erfolgt aber keine Prüfung auf Plausibilität! </remarks> */ public float Geschwindigkeit { get { return geschwindigkeit; } set { geschwindigkeit = value; } } // --------------------------------------------------------------------- /** <summary> Property für den gerade eingelegten Gang. </summary> <remarks> Set-Methode: Es erfolgt eine Prüfung auf Gültigkeit! <p> Der eingelegte Gang kann nicht kleiner sein als 1 und nicht höher als die Anzahl der Gänge. <br /> Bei einem Fehler wird der Gang nicht geändert. </p> </remarks> */ public int Gang { get { return gang; } set { if ((value >= 1) && (value <= anzahlGaenge)) { gang = value; } } } // --------------------------------------------------------------------- /** <summary> Property für den Besitzer des Autos. </summary> */ public Person Besitzer { get { return besitzer; } set { besitzer = value; } } // --------------------------------------------------------------------- // Instanzmethoden // --------------------------------------------------------------------- /** <summary> Gang um 1 erhöhen. </summary> */ public void Raufschalten() { if (gang < anzahlGaenge) { gang = gang + 1; } } // ---------- /** <summary> Gang um 1 vermindern. </summary> */ public void Runterschalten() { if (gang > 1) { gang = gang - 1; } } // ---------- /** <summary> Geschwindigkeit um 10% erhöhen. </summary> */ public void Beschleunigen() { geschwindigkeit = geschwindigkeit * 1.1f; } // ---------- /** <summary> Geschwindigkeit um 10% vermindern. </summary> */ public void Bremsen() { geschwindigkeit = geschwindigkeit * 0.9f; } // --------------------------------------------------------------------- /** <summary> Schreibt alle Attribute in die Standardausgabe. <br /> Achtung: Besitzer sollte bereits initialisiert sein! </summary> <remarks> Anstelle dieser Methode sollte besser die Methode 'Object.ToString()' überschrieben werden. </remarks> */ public void ZeigeInhalt() { Console.WriteLine(GetType().FullName + "-Daten: [ Mehrwertsteuersatz = " + mwstSatz + "%" ); Console.WriteLine(" Besitzer = " + besitzer.Heisst() + ", Farbe = " + farbe + ", Anzahl Gaenge = " + anzahlGaenge ); Console.WriteLine(" eingelegter Gang = " + gang + " / aktuelle Geschwindigkeit = " + geschwindigkeit + " ]" ); } // --------------------------------------------------------------------- // Methode 'ToString' // --------------------------------------------------------------------- /** <summary> Überschreiben der Methode 'String Object.ToString()'. <p> Achtung: Besitzer sollte bereits initialisiert sein! </p> </summary> <remarks> Liefert eine beschreibende Text-Darstellung einer Instanz der Klasse: <pre> Auto-Daten: [ Mehrwertsteuersatz = ...% Besitzer = ..., Farbe = ..., Anzahl Gaenge = ... eingelegter Gang = ... / aktuelle Geschwindigkeit = ... ] </pre> <p> Hinweis: Statt der Klasse 'String' sollte die Klasse 'StringBuilder' verwendet werden! </p> <seealso cref="System.Object#toString()" /> </remarks> <returns> Zeichenkette, die eine Instanz beschreibt </returns> */ override public String ToString() { String neueZeile = Environment.NewLine; // Zugriff auf Attribute nur über Zugriffsmethoden und Properties // (Datenkapselung): return GetType().FullName + "-Daten: [ Mehrwertsteuersatz = " + MwstSatz() + "%" + neueZeile + " Besitzer = " + Besitzer.Heisst() + ", Farbe = " + Farbe + ", Anzahl Gaenge = " + AnzahlGaenge + neueZeile + " eingelegter Gang = " + Gang + " / aktuelle Geschwindigkeit = " + Geschwindigkeit + " ]" ; } // --------------------------------------------------------------------- // Klassenmethoden // --------------------------------------------------------------------- /** <summary> Liefert den Mehrwertsteuersatz. </summary> <returns> Mehrwertsteuersatz </returns> */ public static int MwstSatz() { return mwstSatz; } // ---------- /** <summary> Ändert den Mehrwertsteuersatz. </summary> <param name="value"> neuer Mehrwertsteuersatz </param> */ public static void MwstSatz(int value) { mwstSatz = value; } } } |
Klasse Datum |
---|
/* * Datum.cs */ using System; namespace Beringer.oopBuch.EinfacheBsp { /** <summary> Eine einfache Datumsklasse. <p> Seit: November 2004 </p> <seealso cref="DatumTesten" /> <seealso cref="Beringer.oopBuch.EinfacheBspProgramme.ProgrammDatumTesten"/> <seealso cref="System.DateTime" /> Autor: Beringer Alfred </summary> <remarks> Instanzen dieser Klasse können kopiert werden. </remarks> */ public class Datum : ICloneable { // --------------------------------------------------------------------- // Klassenkonstante // --------------------------------------------------------------------- private static readonly String[] Monatsnamen = { "Jänner ", "Februar ", "März ", "April ", "Mai ", "Juni ", "Juli ", "August ", "September", "Oktober ", "November ", "Dezember " }; private static readonly int[] TageProMonat = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; private static readonly int[] LfdTagMonatsanfang = { 1, 32, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335 }; // --------------------------------------------------------------------- // Instanzattribute // --------------------------------------------------------------------- private int jj; private int mm; private int tt; // --------------------------------------------------------------------- // Konstruktoren // --------------------------------------------------------------------- /** <summary> Standardkonstruktor. </summary> <remarks> Initialisierung mit aktuellem Tagesdatum </remarks> */ public Datum() { DateTime heute = DateTime.Today; // liefert aktuelles Tagesdatum jj = heute.Year; mm = heute.Month; tt = heute.Day; } // --------------------------------------------------------------------- /** <summary> Initialisierung mit einem beliebigen Tagesdatum. </summary> <remarks> Dieses Datum wird auf Gültigkeit geprüft, bei einem Fehler wird das aktuelle Tagesdatum zur Initialisierung verwendet. </remarks> <param name="jahr"> Jahr </param> <param name="monat"> Monatsnummer (bei 1 (= Jänner) beginnend) </param> <param name="tag"> Tag </param> */ public Datum(int jahr, int monat, int tag) : this() // initialisieren mit aktuellem Tagesdatum { setDatum(jahr, monat, tag); } // --------------------------------------------------------------------- // Properties // --------------------------------------------------------------------- /** <summary> Get-Property für das Jahr. </summary> */ public int JJ { get { return jj; } } // ---------- /** <summary> Get-Property für die Monatsnummer. </summary> */ public int MM { get { return mm; } } // ---------- /** <summary> Get-Property für den Tag. </summary> */ public int TT { get { return tt; } } // ---------- /** <summary> Get-Property für den Monatsnamen entsprechend der Monatsnummer. </summary> */ public String Monatsname { get { return Monatsnamen[mm-1]; } } // --------------------------------------------------------------------- // Private Set-Methoden // --------------------------------------------------------------------- /** <summary> Prüft und setzt ein korrektes Datum. </summary> <remarks> Der Einfachheit halber werden Fehlermeldungen auf die Konsole geschrieben. </remarks> <param name="jahr"> Jahr </param> <param name="monat"> Monatsnummer (bei 1 (= Jänner) beginnend) </param> <param name="tag"> Tag </param> <returns> true, wenn das Datum korrekt ist </returns> */ private bool setDatum(int jahr, int monat, int tag) { int tageProMonat; if (jahr == 0) { Console.WriteLine("Fehler: " + jahr + " ist ungültig"); return false; } if ((monat < 1) || (monat > 12)) { Console.WriteLine("Fehler: " + monat + " ist ungültig"); return false; } tageProMonat = TageProMonat[monat - 1]; if ((monat == 2) && (Datum.IstSchaltjahr(jahr))) { tageProMonat++; } if ((tag < 1) || (tag > tageProMonat)) { Console.WriteLine("Fehler: " + tag + " ist ungültig"); return false; } jj = jahr; mm = monat; tt = tag; return true; } // --------------------------------------------------------------------- // Instanzmethoden // --------------------------------------------------------------------- /** <summary> Liefert den laufenden Tag des Jahres. </summary> <returns> laufender Tag des Jahres </returns> */ public int LfdTagDesJahres() { int lfd; lfd = LfdTagMonatsanfang[mm-1] + tt - 1; if ((mm > 2) && (this.IstSchaltjahr())) { lfd++; } return lfd; } // --------------------------------------------------------------------- /** <summary> Prüft das eigene Jahr auf Schaltjahr. </summary> <returns> true, wenn das eigene Jahr ein Schaltjahr ist </returns> */ public bool IstSchaltjahr() { return Datum.IstSchaltjahr(jj); } // --------------------------------------------------------------------- // Methoden 'ToString' und 'Clone' // --------------------------------------------------------------------- /** <summary> Überschreiben der Methode 'String Object.toString()'. </summary> <remarks> Liefert eine beschreibende Text-Darstellung einer Instanz der Klasse: <pre> TT. MM. JJJJ </pre> <seealso cref="System.Object#ToString()" /> </remarks> <returns> Datum in der Form "TT. MM. JJJJ" </returns> */ override public String ToString() { return TT + ". " + MM + ". " + JJ; } // --------------------------------------------------------------------- /** <summary> Abstrakte Methode 'Clone()' von 'ICloneable' definieren. <p> Kopieren einer Datum-Instanz (tiefe Kopie): <ol> <li>Sichtbarkeit auf 'public' anheben ('ICloneable.Clone()' ist 'protected'!).</li> <li>Vererbte Methode 'Object.MemberwiseClone()' aufrufen ('base.MemberwiseClone()').</li> <li>Veränderliche Attribute kopieren: <br /> Da diese Klasse keine veränderlichen Attribute hat, ist für eine tiefe Kopie nichts weiter zu tun. <br /> (Wenn bereits in get-/set-Properties nur Kopien von veränderlichen Attributen verwendet werden, könnten diese Properties für das Kopieren dieser Attribute verwendet werden.</li> </ol> <seealso cref="System.Object#MemberwiseClone()" /> </summary> <returns> (tiefe) Kopie eines Datums </returns> */ public Object Clone() { Datum datumKopie; datumKopie = (Datum) base.MemberwiseClone(); /* hier folgt das Kopieren der veränderlichen Attribute (für eine tiefe Kopie) z.B.: kopie.Attribut = Attribut; */ return datumKopie; } // --------------------------------------------------------------------- // Klassenmethoden // --------------------------------------------------------------------- /** <summary> Liefert das aktuelle Tagesdatum. </summary> <returns> Instanz des aktuellen Tagesdatums </returns> */ public static Datum Heute() { return new Datum(); } // --------------------------------------------------------------------- /** <summary> Prüft ein vorgegebenes Jahr auf Schaltjahr. </summary> <param name="jahr"> zu prüfende Jahreszahl </param> <returns> true, wenn 'jahr' ein Schaltjahr ist </returns> */ public static bool IstSchaltjahr(int jahr) { return ((jahr%4 != 0) || ((jahr%100 == 0) && (jahr%400 != 0))) ? false : true; } } } |
2.5.3 Smalltalk
Die nachfolgenden Beispiele liegen im Namensbereich BeringerEinfacheBsp
(siehe Kap.10.3).
Klasse Zaehler |
---|
Smalltalk.BeringerEinfacheBsp defineClass: #Zaehler
superclass: #{Core.Object}
indexedType: #none
private: false
instanceVariableNames: 'wert '
classInstanceVariableNames: ''
imports: ''
category: 'EinfacheBeispiele'
Kommentar
Instanzen dieser Klasse repräsentieren einen einfachen Zähler, der
(um 1) erhöht und (auf 0) zurückgesetzt werden kann.
Instanzvariable:
wert <Integer> aktueller Wert des Zählers
Anwendungsbeispiel:
| z |
z := Zaehler new.
z erhoehen.
z wert
BeringerEinfacheBsp.Zaehler Klassenprotokoll instance creation new ^ super new reset BeringerEinfacheBsp.Zaehler Protokoll accessing wert ^ wert BeringerEinfacheBsp.Zaehler Protokoll berechnungen erhoehen self wert: (self wert + 1). "Einfacher, aber mit weniger Datenkapselung: wert := wert + 1 " ^ self wert reset self wert: 0 "Einfacher, aber mit weniger Datenkapselung: wert := 0 " BeringerEinfacheBsp.Zaehler Protokoll private wert: neuerWert wert := neuerWert |
Klasse Zaehler2 |
---|
Smalltalk.BeringerEinfacheBsp defineClass: #Zaehler2
superclass: #{Core.Object}
indexedType: #none
private: false
instanceVariableNames: 'wert '
classInstanceVariableNames: 'Endwert '
imports: ''
category: 'EinfacheBeispiele'
Kommentar
Instanzen dieser Klasse repräsentieren einen einfachen zweistelligen Zähler,
der (um 1) erhöht und (auf 0) zurückgesetzt werden kann.
Der Zähler beginnt nach 99 (= Standardwert für Endwert) wieder bei 0,
d.h. bei 100 erfolgt ein Überlauf.
Klasseninstanzvariable:
Endwert <Integer> Maximalwert des Zählers
Instanzvariable:
wert <Integer> aktueller Wert des Zählers
BeringerEinfacheBsp.Zaehler2 Klassenprotokoll class initialization initialize "Für einen zweistelligen Zähler wird der Endwert auf 99 gesetzt." Endwert := 99 BeringerEinfacheBsp.Zaehler2 Klassenprotokoll instance creation new ^ super new reset BeringerEinfacheBsp.Zaehler2 Klassenprotokoll accessing endwert ^ Endwert endwert: endwert Endwert := endwert BeringerEinfacheBsp.Zaehler2 Protokoll accessing wert ^ wert BeringerEinfacheBsp.Zaehler2 Protokoll berechnungen erhoehen self wert: (self wert + 1). ^ self wert reset self wert: 0 BeringerEinfacheBsp.Zaehler2 Protokoll private wert: neuerWert wert := neuerWert. ( (self wert > self class endwert) or: [self wert < 0] ) ifTrue: [ self reset ] BeringerEinfacheBsp.Zaehler2 initialize |
Klasse Person |
---|
Smalltalk.BeringerEinfacheBsp defineClass: #Person
superclass: #{Core.Object}
indexedType: #none
private: false
instanceVariableNames: 'vorname geburtsjahr geschlecht '
classInstanceVariableNames: ''
imports: ''
category: 'EinfacheBeispiele'
Kommentar
Jede Instanz dieser Klasse repräsentiert eine natürliche Person.
Hinweis: Die Namen der Standardzugriffsmethoden entsprechen NICHT den
üblichen Smalltalk- bzw. UML-Konventionen!
Klassenvariable:
MAENNLICH <Character> Kennzeichen männlich = M
WEIBLICH <Character> Kennzeichen weiblich = W
Instanzvariable:
vorname <String> Vorname
geburtsjahr <Integer> Geburtsjahr
geschlecht <Character> männlich oder weiblich
BeringerEinfacheBsp.Person defineSharedVariable: #MAENNLICH private: false constant: true category: 'Klassenvariable' initializer: '$M' BeringerEinfacheBsp.Person defineSharedVariable: #WEIBLICH private: false constant: true category: 'Klassenvariable' initializer: '$W' BeringerEinfacheBsp.Person Klassenprotokoll instance creation newGeburtsjahr: einJahr geschlecht: kennzeichen "Jede Person muss ein Geburtsjahr und ein Geschlecht haben." ^ (super new) aendernGeburtsjahr: einJahr; aendernGeschlecht: kennzeichen; initialize new "Eine Personeninstanz kann nur mit Geburtsdatum und Geschlecht erzeugt werden." self error: 'Keine Daten (Geburtsdatum und Geschlecht sind anzugeben)' BeringerEinfacheBsp.Person Protokoll initialize-release initialize super initialize. ^ self BeringerEinfacheBsp.Person Protokoll accessing heisst ^ vorname aendernVorname: neuerVorname vorname := neuerVorname geboren ^ geburtsjahr hatGeschlecht ^ geschlecht BeringerEinfacheBsp.Person Protokoll berechnungen anrede (self hatGeschlecht = MAENNLICH) ifTrue: [ ^ 'Sehr geehrter Herr' ]. ^ 'Sehr geehrte Frau' alterBerechnen "Liefert das Alter des Empfängers in Anzahl von Jahren (ohne Berücksichtigung des Monats). 'Date' ist eine Standardklasse von VisualWorks." ^ (Date today year - self geboren year) BeringerEinfacheBsp.Person Protokoll private aendernGeburtsjahr: einJahr (einJahr <= Date today year) ifTrue: [ geburtsjahr := einJahr. ^ true ]. "ungültiges Geburtsjahr" ^ false aendernGeschlecht: kennzeichen ( (kennzeichen = MAENNLICH) or: [kennzeichen = WEIBLICH] ) ifTrue: [ geschlecht := kennzeichen. ^ true ]. "ungültiges Kennzeichen für Geschlecht" ^ false BeringerEinfacheBsp.Person Protokoll printing printOn: aStream "Dient zur textuellen Darstellung einer Personeninstanz. Ermöglicht der Methode 'printString' eine sinnvolle Ausgabe." aStream nextPutAll: self class name , ': ' , self heisst printString , ' (' , self geboren printString , ') ' |
Klasse Auto |
---|
Smalltalk.BeringerEinfacheBsp defineClass: #Auto
superclass: #{Core.Object}
indexedType: #none
private: false
instanceVariableNames: 'farbe anzahlGaenge geschwindigkeit gang besitzer '
classInstanceVariableNames: 'MwstSatz'
imports: ''
category: 'EinfacheBeispiele'
Kommentar
Jede Instanz dieser Klasse repräsentiert ein Auto.
Klasseninstanzvariable:
MwstSatz <Float> Mehrwertsteuersatz
Instanzvariable:
farbe <String> Farbe des Autos
anzahlGaenge <Integer> Anzahl der Gänge
geschwindigkeit <Float> aktuelle Geschwindigkeit
gang <Integer> eingelegter Gang
besitzer <Person> Besitzer des Autos
BeringerEinfacheBsp.Auto Klassenprotokoll class initialization initialize MwstSatz := 20 BeringerEinfacheBsp.Auto Klassenprotokoll instance creation new ^ super new initialize BeringerEinfacheBsp.Auto Klassenprotokoll accessing mwstSatz ^ MwstSatz mwstSatz: mwstSatz MwstSatz := mwstSatz BeringerEinfacheBsp.Auto Protokoll initialize-release initialize super initialize. self besitzer: nil. self farbe: 'rot'. self anzahlGaenge: 5. self geschwindigkeit: 10.0. self gang: 1. ^ self BeringerEinfacheBsp.Auto Protokoll accessing farbe ^ farbe farbe: neueFarbe farbe := neueFarbe anzahlGaenge ^ anzahlGaenge anzahlGaenge: neueAnzahlGaenge (neueAnzahlGaenge >= 1) ifTrue: [ anzahlGaenge := neueAnzahlGaenge ]. self gang: 1 geschwindigkeit ^ geschwindigkeit geschwindigkeit: neueGeschwindigkeit geschwindigkeit := neueGeschwindigkeit gang ^ gang gang: neuerGang ( (neuerGang >= 1) and: [neuerGang <= anzahlGaenge] ) ifTrue: [ gang := neuerGang ] besitzer ^ besitzer besitzer: neuerBesitzer besitzer := neuerBesitzer BeringerEinfacheBsp.Auto Protokoll berechnungen raufschalten (gang < anzahlGaenge) ifTrue: [ gang := gang + 1 ] runterschalten (gang > 1) ifTrue: [ gang := gang - 1 ] beschleunigen geschwindigkeit := geschwindigkeit * 1.1 bremsen geschwindigkeit := geschwindigkeit * 0.9 BeringerEinfacheBsp.Auto Protokoll printing zeigeInhalt "Schreibt alle Attribute in die Standardausgabe. Anstelle dieser Methode sollte besser die Methode 'printOn:' überschrieben werden. Achtung: Besitzer sollte bereits initialisiert sein!" Transcript cr; show: self class name , '-Daten: [ Mehrwertsteuersatz = ' , self class mwstSatz printString , '%'; cr; show: ' Besitzer = ' , self besitzer heisst printString , ', Farbe = ' , self farbe printString , ', Anzahl Gänge = ' , self anzahlGaenge printString; cr; show: ' eingelegter Gang = ' , self gang printString , ' / aktuelle Geschwindigkeit = ' , self geschwindigkeit printString , ' ]' printOn: aStream "Vererbte Methode 'printOn:' überschreiben. Dient zur textuellen Darstellung einer Auto-Instanz. Ermöglicht der Methode 'printString' eine sinnvolle Ausgabe. Achtung: Besitzer sollte bereits initialisiert sein! String-Darstellung einer Auto-Instanz: Auto-Daten: [ Mehrwertsteuersatz = ...% Besitzer = ..., Farbe = ..., Anzahl Gänge = ... eingelegter Gang = ... / aktuelle Geschwindigkeit = ... ]" aStream nextPutAll: self class name , '-Daten: [ Mehrwertsteuersatz = ' , self class mwstSatz printString , '%'; cr; nextPutAll: ' Besitzer = ' , self besitzer heisst printString , ', Farbe = ' , self farbe printString , ', Anzahl Gänge = ' , self anzahlGaenge printString; cr; nextPutAll: ' eingelegter Gang = ' , self gang printString , ' / aktuelle Geschwindigkeit = ' , self geschwindigkeit printString , ' ]' BeringerEinfacheBsp.Auto initialize |
Klasse Datum |
---|
Smalltalk.BeringerEinfacheBsp defineClass: #Datum
superclass: #{Core.Object}
indexedType: #none
private: false
instanceVariableNames: 'jj mm tt '
classInstanceVariableNames: ''
imports: ''
category: 'EinfacheBeispiele'
Kommentar
Eine einfache Datumsklasse.
Klassenvariable:
Monatsnamen <String-Array> Monatsnamen
TageProMonat <Integer-Array> Anzahl Tage pro Monat
LfdTagMonatsanfang <Integer-Array> Laufende Tagesnummer des
Monatsersten
Instanzvariable:
jj <Integer> Jahr
mm <Integer> Monat
tt <Integer> Tag
BeringerEinfacheBsp.Datum defineSharedVariable: #Monatsnamen private: false constant: true category: 'Klassenvariable' initializer: '#("Jänner " "Februar " "März " "April " "Mai " "Juni " "Juli " "August " "September" "Oktober " "November " "Dezember ")' BeringerEinfacheBsp.Datum defineSharedVariable: #TageProMonat private: false constant: true category: 'Klassenvariable' initializer: '#(31 28 31 30 31 30 31 31 30 31 30 31)' BeringerEinfacheBsp.Datum defineSharedVariable: #LfdTagMonatsanfang private: false constant: true category: 'Klassenvariable' initializer: '#(1 32 60 91 121 152 182 213 244 274 305 335)' BeringerEinfacheBsp.Datum Klassenprotokoll instance creation newJahr: jahr monatsNummer: monat tag: tag ^ (super new) jj: jahr mm: monat tt: tag new | heute | heute := Date today. ^ Datum newJahr: heute year monatsNummer: heute monthIndex tag: heute dayOfMonth heute ^ Datum new BeringerEinfacheBsp.Datum Klassenprotokoll testing istSchaltjahr: jahr (jahr \\ 4 ~= 0 or: [ jahr \\ 100 = 0 and: [jahr \\ 400 ~= 0] ]) ifTrue: [ ^ false ]. ^ true BeringerEinfacheBsp.Datum Protokoll accessing jj ^ jj mm ^ mm tt ^ tt monatsname ^ Monatsnamen at: self mm BeringerEinfacheBsp.Datum Protokoll berechnungen lfdTagDesJahres | lfd | lfd := (LfdTagMonatsanfang at: self mm) + self tt - 1. ( self mm > 2 and: [ self istSchaltjahr ] ) ifTrue: [ lfd := lfd + 1. ]. ^ lfd BeringerEinfacheBsp.Datum Protokoll testing istSchaltjahr ^ self class istSchaltjahr: self jj BeringerEinfacheBsp.Datum Protokoll private jj: jahr mm: monat tt: tag "Datum wird geprüft. Die Fehlerbehandlung ist der Einfachheit halber sehr primitiv, denn ein falsches Datum bewirkt einen Programmabsturz!" | tageProMonat | (jahr = 0) ifTrue: [ self error: 'ungültiges Jahr' ]. ( monat < 1 or: [monat > 12] ) ifTrue: [ self error: 'ungültiger Monat' ]. tageProMonat := TageProMonat at: monat. ( monat = 2 and: [Datum istSchaltjahr: jahr] ) ifTrue: [ tageProMonat := tageProMonat + 1 ]. ( tag < 1 or: [tag > tageProMonat] ) ifTrue: [ self error: 'ungültiger Tag' ]. jj := jahr. mm := monat. tt := tag BeringerEinfacheBsp.Datum Protokoll printing printOn: aStream "Datum in Form von TT. MM. JJJJ." aStream nextPutAll: self tt printString , '. ' , self mm printString , '. ' , self jj printString |
- Weiter
- zur Parameterübergabe (Kapitel 2.7.1)
- zu Kapitel 3
- zu den Klassenbeispielen von Kapitel 4
- 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)
- zu Kapitel 3
- Zurück
- zum Anfang dieses Kapitels
- zum Inhaltsverzeichnis
- zu Kapitel 1
- zum Inhaltsverzeichnis
- Zur
- Java-Dokumentation der Java-Beispiele