Skip to Content

Beispielprogramme aus der Vorlesung

Stefan Schneider's picture

Klasse Konto1

Beispiel eines Bankkontos. In der main() Methode werden einfache Überweisungsoperationen ausgeführt.

Welche inkorrekten Aufrufe können in dieser Klasse erfolgen?

package Kurs2.Exception.Demo;
public class Konto1 {
int betrag;
public Konto1(int startBetrag) {
betrag = startBetrag;
}
private void einzahlen(int b) {
betrag += b;
}
private void auszahlen(int b) {
betrag -= b;
}
public void ueberweisenAuf (Konto b, int wert) {
auszahlen(wert);
b.einzahlen(wert);
}
@Override
public String toString() {return betrag + " Euro";}
/**
* Die main Methode sei eine Methode die von einem Team gepflegt wird
* welches nichts von der internen Implementierung der Klasse weis.
* Die Methode wurde nur aus Gründen der Kompaktheit in dieser Klasse
* implementiert
* @param args
*/
public static void main(String[] args) {
Konto1 a1 = new Konto1(500);
Konto1 a2 = new Konto1(100);
a2.ueberweisenAuf(a1, 50);
System.out.println("a1: "+ a1 + "; a2= " +a2);
a2.ueberweisenAuf(a1, -500);
System.out.println("a1: "+ a1 + "; a2= " +a2);
}
}

Klasse Konto2

In diesem Beispiel werden die Methoden so modifiziert, dass sie einen Wahrheitswert zurückgeben der über die korrekte Ausführung informiert.

Welche Nachteile hat eine solche Implementierung?

package Kurs2.Exception.Demo;
public class Konto2 {
int betrag;
public Konto2(int startBetrag) {
betrag = startBetrag;
}
private boolean einzahlen(int b) {
if (b>=0) {
betrag += b;
return true;
}
else return false;
}
private boolean auszahlen(int b) {
if (b>=0) {
betrag -= b;
return true;
}
else return false;
}

public boolean ueberweisenAuf (Konto2 b, int wert) {
boolean korrekt;
korrekt =auszahlen(wert);
if (korrekt)
korrekt= b.einzahlen(wert);
return korrekt;
}

@Override
public String toString() {return betrag + " Euro";}
/**
* Die main Methode sei eine Methode die von einem Team gepflegt wird
* welches nicht die interne Implementierung der Klasse.
* Die Methode wurde nur aus Gründen der Kompaktheit in dieser Klasse
* implementiert
* @param args
*/
public static void main(String[] args) {
Konto2 a1 = new Konto2(500);
Konto2 a2 = new Konto2(100);
boolean korrekt;
korrekt = a2.ueberweisenAuf(a1, 50);
if (korrekt)
System.out.println("a1: "+ a1 + "; a2= " +a2);
else
System.out.println("Fehler; a1: "+ a1 + "; a2= " +a2);
korrekt = a2.ueberweisenAuf(a1, -500);
if (korrekt)
System.out.println("a1: "+ a1 + "; a2= " +a2);
else
System.out.println("Fehler; a1: "+ a1 + "; a2= " +a2);
}
}

Kasse Konto3

In dieser Implementierung werden "Assertions" verwendet.

Die Verwendung der Assertion wird mit Hilfe der Option -ea aktiviert.

Wir das Programm mit dem Befehl

$ java -ea Kurs2.Exception.Demo.Konto3

gestartet, werden die Assertions ausgeführt und geprüft. Das Programm wird bei der ersten Verletzung einer Assertion beendet.

package Kurs2.Exception.Demo;
public class Konto3 {
int betrag;
public Konto3(int startBetrag) {
betrag = startBetrag;
}
private void einzahlen(int b) {
assert (b>=0): "Versuch " + b + " zu einzuzahlen";
betrag += b;
}
private void auszahlen(int b) {
assert (b>=0): "Versuch " + b + " zu auszuzahlen";
betrag -= b;
}
public void ueberweisenAuf (Konto3 b, int wert) {
auszahlen(wert);
b.einzahlen(wert);
}
@Override
public String toString() {return betrag + " Euro";}
/**
* Die main Methode sei eine Methode die von einem Team gepflegt wird
* welches nichts von der internen Implementierung der Klasse weis.
* Die Methode wurde nur aus Gründen der Kompaktheit in dieser Klasse
* implementiert
* @param args
*/
public static void main(String[] args) {
Konto3 a1 = new Konto3(500);
Konto3 a2 = new Konto3(100);
boolean korrekt;
a2.ueberweisenAuf(a1, 50);
System.out.println("a1: "+ a1 + "; a2= " +a2);
a2.ueberweisenAuf(a1, -500);
System.out.println("a1: "+ a1 + "; a2= " +a2);
}
}

Klasse Konto4

Das Verwenden von Assertions in den privaten Methoden einzahlen() und auszahlen() ist sinnvoll, da die beidenMethoden können nur innerhalb der Klasse aufgerufen werden können. Der Entwickler der Klasse kann garantieren, dass sie immer mit korrekten Werten aufgerufen werden sollten.

In der folgenden Klasse wir die Methode ueberweisenAuf() auch mit einer Assertion geschützt. Die Methode ist öffentlich und kann auch von externen Klassen aufgerufen werden.

Warum ist dies keine gute Implementierung?

package Kurs2.Exception.Demo;
public class Konto4 {
int betrag;
public Konto4(int startBetrag) {
betrag = startBetrag;
}
private void einzahlen(int b) {
assert (b>=0);
betrag += b;
}
private void auszahlen(int b) {
assert (b>=0);
betrag -= b;
}
public void ueberweisenAuf (Konto4 b, int wert) {
assert(wert>=0): "Versuch einer negativen Überweisung von " + wert ;
auszahlen(wert);
b.einzahlen(wert);
}
@Override
public String toString() {return betrag + " Euro";}
/**
* Die main Methode sei eine Methode die von einem Team gepflegt wird
* welches nichts von der internen Implementierung der Klasse weis.
* Die Methode wurde nur aus Gründen der Kompaktheit in dieser Klasse
* implementiert
* @param args
*/
public static void main(String[] args) {
Konto4 a1 = new Konto4(500);
Konto4 a2 = new Konto4(100); boolean korrekt; a2.ueberweisenAuf(a1, 50); System.out.println("a1: "+ a1 + "; a2= " +a2); a2.ueberweisenAuf(a1, -500); System.out.println("a1: "+ a1 + "; a2= " +a2); } }

Klasse Konto5

Die Klasse Konto5 erweitert die Implementierung. Es wird ein Überweisungslimit eingeführt. Das Überweisungslimit wird im Konstruktor erfasst. Es sollen keine Überweisungen mit einem höheren Betrag als dem Überweisungslimit ausgeführt.

package Kurs2.Exception.Demo;
public class Konto5 {
int betrag;
private int ueberweisungsLimit;
private static final int MINLIMIT =1;
public Konto5(int startBetrag, int ll) {
betrag = startBetrag;
if (ll>0) ueberweisungsLimit=ll;
else ueberweisungsLimit = MINLIMIT;
}
private void einzahlen(int b) {
assert (b>=0);
betrag += b;
}
private void auszahlen(int b) {
assert (b>=0);
betrag -= b;
}
public void ueberweisenAuf (Konto5 b, int wert) {
assert(wert>=0);
auszahlen(wert);
b.einzahlen(wert);
}
@Override
public String toString() {return betrag + " Euro";}
/**
* Die main Methode sei eine Methode die von einem Team gepflegt wird
* welches nichts von der internen Implementierung der Klasse weis.
* Die Methode wurde nur aus Gründen der Kompaktheit in dieser Klasse
* implementiert
* @param args
*/
public static void main(String[] args) {
Konto5 a1 = new Konto5(500, 50);
Konto5 a2 = new Konto5(100, 80);
boolean korrekt;
a2.ueberweisenAuf(a1, 50);
System.out.println("a1: "+ a1 + "; a2= " +a2);
a2.ueberweisenAuf(a1, -500);
System.out.println("a1: "+ a1 + "; a2= " +a2);
a2.ueberweisenAuf(a1, 100);
System.out.println("a1: "+ a1 + "; a2= " +a2);
}
}

Klasse Konto6

In dieser Implementierung werden inkorrekte Überweisungen mit negativen Beträgen oder Beträgen jenseits des Überweisungslimit mit Hilfe von unterschiedlichen Rückgabewerten und Konstanten gemeldet.

Die gewählte Implementierung vermeidet Fehler und meldet diese ausführlich.

Die Behandlung der Fehlerwerte ist jedoch aufwändig.

package Kurs2.Exception.Demo;
public class Konto6 {
int betrag;
private int ueberweisungsLimit;
private static final int MINLIMIT =1;
public static final int OK = 0;
public static final int NEGATIVERWERT = 1;
public static final int LIMITUEBERSCHRITTEN = 2;
public Konto6(int startBetrag, int ll) {
betrag = startBetrag;
if (ll>0) ueberweisungsLimit=ll;
else ueberweisungsLimit = MINLIMIT;
}
private void einzahlen(int b) {
assert (b>=0);
betrag += b;
}
private void auszahlen(int b) {
assert (b>=0);
betrag -= b;
}
public int ueberweisenAuf (Konto6 b, int wert) {
if (wert < 0) return NEGATIVERWERT;
else
if ((wert > ueberweisungsLimit )|| (wert > b.ueberweisungsLimit ))
return LIMITUEBERSCHRITTEN;
else {
auszahlen(wert);
b.einzahlen(wert);
return OK;
}
}
@Override
public String toString() {return betrag + " Euro";}
/**
* Die main Methode sei eine Methode die von einem Team gepflegt wird
* welches nichts von der internen Implementierung der Klasse weis.
* Die Methode wurde nur aus Gründen der Kompaktheit in dieser Klasse
* implementiert
* @param args
*/
public static void main(String[] args) {
Konto6 a1 = new Konto6(500, 50);
Konto6 a2 = new Konto6(100, 80);
int status;
status = a2.ueberweisenAuf(a1, 50);
if (status != OK)
System.out.println("Fehler: " + status);

else
System.out.println("a1: "+ a1 + "; a2= " +a2);
status = a2.ueberweisenAuf(a1, -500);
if (status != OK)
System.out.println("Fehler: " + status);
else
System.out.println("a1: "+ a1 + "; a2= " +a2);
status = a2.ueberweisenAuf(a1, 100);
if (status != OK)
System.out.println("Fehler: " + status);
else
System.out.println("a1: "+ a1 + "; a2= " +a2);
}
}

Klasse Konto7 und Ueberweisungsausnahme

 In dieser Implementierung werden Ausnahmen (Exceptions) verwendet um eine Ausnahmebehandlung durchzuführen.

package Kurs2.Exception.Demo;
public class Konto7 {
int betrag;
private int ueberweisungsLimit;
private static final int MINLIMIT =1;
public static final int OK = 0;
public static final int NEGATIVERWERT = 1;
public static final int LIMITUEBERSCHRITTEN = 2;
public Konto7(int startBetrag, int ll) {
betrag = startBetrag;
if (ll>0) ueberweisungsLimit=ll;
else ueberweisungsLimit = MINLIMIT;
}
private void einzahlen(int b) {
assert (b>=0);
betrag += b;
}
private void auszahlen(int b) {
assert (b>=0);
betrag -= b;
}
public void ueberweisenAuf (Konto7 b, int wert) {
if (wert < 0) throw new UeberweisungsAusnahme("Negativer Wert" + wert);
else
if (wert > ueberweisungsLimit )
throw new UeberweisungsAusnahme("Limit ueberschritten " + wert
+ "; Limit: " + ueberweisungsLimit);

else
if (wert > b.ueberweisungsLimit )
throw new UeberweisungsAusnahme("Limit ueberschritten " + wert
+ "; Limit: " + b.ueberweisungsLimit);

else {
auszahlen(wert);
b.einzahlen(wert);
}
}
@Override
public String toString() {return betrag + " Euro";}
/**
* Die main Methode sei eine Methode die von einem Team gepflegt wird
* welches nichts von der internen Implementierung der Klasse weis.
* Die Methode wurde nur aus Gründen der Kompaktheit in dieser Klasse
* implementiert
* @param args
*/
public static void main(String[] args) {
Konto7 a1 = new Konto7(500, 50);
Konto7 a2 = new Konto7(100, 80);
int status;
a2.ueberweisenAuf(a1, 50);
System.out.println("a1: "+ a1 + "; a2= " +a2);
a2.ueberweisenAuf(a1, -500);
System.out.println("a1: "+ a1 + "; a2= " +a2);
a2.ueberweisenAuf(a1, 100);
System.out.println("a1: "+ a1 + "; a2= " +a2);
}
}

Die Klasse Ueberweisungsausnahme

Die Klasse wird aus der Klasse IllegalArgumentException abgeleitet. Sie muss nicht behandelt werden da diese Ausnahme eine Spezialisierung der RuntimeException ist. Das Auftreten der Ausnahme im Hauptprogramm kann aber behandelt werden.

package Kurs2.Exception.Demo;
public class UeberweisungsAusnahme extends IllegalArgumentException {
public UeberweisungsAusnahme(String text) {
super(text);
}
}

Klasse Konto8

In der Klasse Konto8 wird in der main() Methode eine geworfene Ausnahme behandelt.

package Kurs2.Exception.Demo;
public class Konto8 {
int betrag;
private int ueberweisungsLimit;
private static final int MINLIMIT =1;
public static final int OK = 0;
public static final int NEGATIVERWERT = 1;
public static final int LIMITUEBERSCHRITTEN = 2;
public Konto8(int startBetrag, int ll) {
betrag = startBetrag;
if (ll>0) ueberweisungsLimit=ll;
else ueberweisungsLimit = MINLIMIT;
}
public void einzahlen(int b) {
assert (b>=0);
betrag += b;
}
public void auszahlen(int b) {
assert (b>=0);
betrag -= b;
}
public void ueberweisenAuf (Konto8 b, int wert) {
if (wert < 0) throw new UeberweisungsAusnahme("Negativer Wert" + wert);
else
if (wert > ueberweisungsLimit )
throw new UeberweisungsAusnahme("Limit ueberschritten " + wert
+ "; Limit: " + ueberweisungsLimit);
else
if (wert > b.ueberweisungsLimit )
throw new UeberweisungsAusnahme("Limit ueberschritten " + wert
+ "; Limit: " + b.ueberweisungsLimit);
else {
auszahlen(wert);
b.einzahlen(wert);
}
}
@Override
public String toString() {return betrag + " Euro";}
/**
* Die main Methode sei eine Methode die von einem Team gepflegt wird
* welches nichts von der internen Implementierung der Klasse weis.
* Die Methode wurde nur aus Gründen der Kompaktheit in dieser Klasse
* implementiert
* @param args
*/
public static void main(String[] args) {
Konto8 a1 = new Konto8(500, 50);
Konto8 a2 = new Konto8(100, 80); int status; a2.ueberweisenAuf(a1, 50); System.out.println("a1: "+ a1 + "; a2= " +a2); try {

a2.ueberweisenAuf(a1, -500);
}
catch (UeberweisungsAusnahme ue) {
System.out.println("Fehler aufgetreten" + ue.getMessage());
System.out.println ("Operation nicht ausgeführt");
}

System.out.println("a1: "+ a1 + "; a2= " +a2);
a2.ueberweisenAuf(a1, 100);
System.out.println("a1: "+ a1 + "; a2= " +a2);
}
}

Konto9

In der Klasse Konto9 wird zwischen einer allgemeinen ÜberweisungsAusnahme und einer LimitAusnahme unterschieden.

package Kurs2.Exception.Demo;
public class Konto9 {
int betrag;
private int ueberweisungsLimit;
private static final int MINLIMIT =1;
public static final int OK = 0;
public static final int NEGATIVERWERT = 1;
public static final int LIMITUEBERSCHRITTEN = 2;
public Konto9(int startBetrag, int ll) {
betrag = startBetrag;
if (ll>0) ueberweisungsLimit=ll;
else ueberweisungsLimit = MINLIMIT;
}
public void einzahlen(int b) {
assert (b>=0);
betrag += b;
}
public void auszahlen(int b) {
assert (b>=0);
betrag -= b;
}
public void ueberweisenAuf (Konto9 b, int wert) {
if (wert < 0) throw new UeberweisungsAusnahme("Negativer Wert" + wert);
else {
int maxlimit = (ueberweisungsLimit<b.ueberweisungsLimit) ?
ueberweisungsLimit: b.ueberweisungsLimit;
if (wert > maxlimit )
throw new LimitAusnahme("Limit ueberschritten " + wert,
maxlimit);

else {
auszahlen(wert);
b.einzahlen(wert);
}
}
}
@Override
public String toString() {return betrag + " Euro";}
/**
* Die main Methode sei eine Methode die von einem Team gepflegt wird
* welches nichts von der internen Implementierung der Klasse weis.
* Die Methode wurde nur aus Gründen der Kompaktheit in dieser Klasse
* implementiert
* @param args
*/
public static void main(String[] args) {
Konto9 a1 = new Konto9(500, 50);
Konto9 a2 = new Konto9(50, 80);
int status;
a2.ueberweisenAuf(a1, 50);
System.out.println("a1: "+ a1 + "; a2= " +a2);
try {
a2.ueberweisenAuf(a1, -500);
}
catch (UeberweisungsAusnahme ue) {
System.out.println("Fehler aufgetreten" + ue.getMessage());
System.out.println ("Operation nicht ausgeführt");
}
System.out.println("a1: "+ a1 + "; a2= " +a2);
a2.ueberweisenAuf(a1, 100);
System.out.println("a1: "+ a1 + "; a2= " +a2);
}
}

Klasse LimitAusnahme

Diese Klasse kann das Limit welches verletzt wurde verwalten. Hierdurch können Nutzer mehr Informationen erhalten und intelligenter reagieren.

package Kurs2.Exception.Demo;
public class LimitAusnahme extends UeberweisungsAusnahme {
public int limit;
public LimitAusnahme(String text, int ll) {
super(text);
limit = ll;
}
}

Klasse Konto10

Die Klasse Konto10 reagiert auf eine Limitverletzung durch mehrere Überweisungen die unter dem Limit bleiben.

package Kurs2.Exception.Demo;
public class Konto10 {
int betrag;
private int ueberweisungsLimit;
private static final int MINLIMIT =1;
public static final int OK = 0;
public static final int NEGATIVERWERT = 1;
public static final int LIMITUEBERSCHRITTEN = 2;
public Konto10(int startBetrag, int ll) {
betrag = startBetrag;
if (ll>0) ueberweisungsLimit=ll;
else ueberweisungsLimit = MINLIMIT;
}
private void einzahlen(int b) {
assert (b>=0);
betrag += b;
}
private void auszahlen(int b) {
assert (b>=0);
betrag -= b;
}
public void ueberweisenAuf (Konto10 b, int wert) {
if (wert < 0) throw new UeberweisungsAusnahme("Negativer Wert" + wert);
else {
int maxlimit = (ueberweisungsLimit<b.ueberweisungsLimit) ?
ueberweisungsLimit: b.ueberweisungsLimit;
if (wert > maxlimit )
throw new LimitAusnahme("Limit ueberschritten " + wert,
maxlimit);
else {
auszahlen(wert);
b.einzahlen(wert);
}
}
}
@Override
public String toString() {return betrag + " Euro";} /**

* Die main Methode sei eine Methode die von einem Team gepflegt wird
* welches nichts von der internen Implementierung der Klasse weis.
* Die Methode wurde nur aus Gründen der Kompaktheit in dieser Klasse
* implementiert
* @param args
*/
public static void main(String[] args) {
Konto10 a1 = new Konto10(500, 50);
Konto10 a2 = new Konto10(100, 80);
int status;
a2.ueberweisenAuf(a1, 50);
System.out.println("a1: "+ a1 + "; a2= " +a2);
try {
a2.ueberweisenAuf(a1, -500);
}
catch (UeberweisungsAusnahme ue) {
System.out.println("Fehler aufgetreten" + ue.getMessage());
System.out.println ("Operation nicht ausgeführt");
}
System.out.println("a1: "+ a1 + "; a2= " +a2);
int betrag = 100;
try {
a2.ueberweisenAuf(a1, betrag);
}
catch (LimitAusnahme ue) {
// Splitte Überweisung in mehrere unter des Limits
int dasLimit = ue.limit;
while (betrag > dasLimit) {
betrag = betrag - dasLimit;
a2.ueberweisenAuf(a1, dasLimit);
System.out.println("a1: "+ a1 + "; a2= " +a2);
}
a2.ueberweisenAuf(a1, betrag);
}

System.out.println("a1: "+ a1 + "; a2= " +a2);
}
}

Klasse Konto11

In der Klasse Konto11 wird eine andere Ausnahme bei einem Überweisungsfehler geworfen. Die Ausnahmeklasse UeberweisungsAusnahme11 ist aus der Klasse Exception abgeleitet.

Da die Ausnahme in der Methode ueberweisenAuf() geworfen wird muss

  • ...dies im Kopf der Methode dokumentiert werden
  • ... bei der Verwendung der Methode ueberweisenAuf() immer ein tra catch Block implementiert werden.
package Kurs2.Exception.Demo;
public class Konto11 {
int betrag;
private int ueberweisungsLimit;
private static final int MINLIMIT =1;
public static final int OK = 0;
public static final int NEGATIVERWERT = 1;
public static final int LIMITUEBERSCHRITTEN = 2;
public Konto11(int startBetrag, int ll) {
betrag = startBetrag;
if (ll>0) ueberweisungsLimit=ll;
else ueberweisungsLimit = MINLIMIT;
}
private void einzahlen(int b) {
assert (b>=0);
betrag += b;
}
private void auszahlen(int b) {
assert (b>=0);
betrag -= b;
}
public void ueberweisenAuf(Konto11 b, int wert) throws UeberweisungsAusnahme11 {
if (wert < 0) throw new UeberweisungsAusnahme11("Negativer Wert" + wert);
else {
int maxlimit = (ueberweisungsLimit<b.ueberweisungsLimit) ?
ueberweisungsLimit: b.ueberweisungsLimit;
if (wert > maxlimit )
throw new LimitAusnahme("Limit ueberschritten " + wert,
maxlimit);
else {
auszahlen(wert);
b.einzahlen(wert);
}
}
}
@Override
public String toString() {return betrag + " Euro";} /**

* Die main Methode sei eine Methode die von einem Team gepflegt wird
* welches nichts von der internen Implementierung der Klasse weis.
* Die Methode wurde nur aus Gründen der Kompaktheit in dieser Klasse
* implementiert
* @param args
*/
public static void main(String[] args) {
Konto11 a1 = new Konto11(500, 50);
Konto11 a2 = new Konto11(100, 80);
int status;
try {
a2.ueberweisenAuf(a1, 50);
System.out.println("a1: "+ a1 + "; a2= " +a2);
a2.ueberweisenAuf(a1, -500);
System.out.println("a1: "+ a1 + "; a2= " +a2);
int betrag = 100;
try {
a2.ueberweisenAuf(a1, betrag);
}
catch (LimitAusnahme ue) {
// Splitte Überweisung in mehrere unter des Limits
int dasLimit = ue.limit;
while (betrag > dasLimit) {
betrag = betrag - dasLimit;
a2.ueberweisenAuf(a1, dasLimit);
System.out.println("a1: "+ a1 + "; a2= " +a2);
}
a2.ueberweisenAuf(a1, betrag);
}
System.out.println("a1: "+ a1 + "; a2= " +a2);
}
catch (UeberweisungsAusnahme11 ue) {
System.out.println("Fehler aufgetreten" + ue.getMessage());
System.out.println ("Eine Überweisung wurde nicht ausgeführt");
}

}
}

Klasse Ueberweisungsausnahme

Die Klasse wird aus der Klasse Exception abgeleitet:

package Kurs2.Exception.Demo;
public class UeberweisungsAusnahme11 extends Exception {
public UeberweisungsAusnahme11(String text) {
super(text);
}
}

 



about seo | book