Senf Geschrieben 19. Dezember 2010 Geschrieben 19. Dezember 2010 (bearbeitet) Hallo, ich muss einen Geldautomaten programmieren. Mit diesem Automaten sollte man eine Karte einschieben, den PIN eingeben und Geld abheben koennen. Die Karte soll mit der Methode "karte_ausgeben" ausgegeben werden koennen und somit sollte der ganze Vorgang abgebrochen werden. (d.h.Zustand wieder auf Standby) Ausserdem sollte bei der ersten falsch eingegebenen PIN der Vorgang abgebrochen werden. Meine Probleme liegen hier: Geld kann ohne Karte bzw PIN abgehoben werden. Ausserdem kann ohne Karte der Falsche PIN eingegeben werden und dann erscheint die Nachricht "Falsche PIN. Vorgang wird abgebrochen.Karte wird ausgegeben. Bitte Karte einwerfen. Ich hoffe es kann mir jemand helfen: Das ist meine Programmierung public class Geldautomat { private int guthaben ; private int neuesGuthaben ; private int Geldbetrag ; private int maxBetrag ; private String PIN ; private String zustand ; private String verfuegbarerZustand ; private String bereiterZustand ; public Geldautomat() { guthaben = 10000 ; PIN = "123"; zustand = "standby" ; bereiterZustand = "bereit" ; //Bereiter Zustand = PIN kann eingegeben werden (d.h. Karte erhalten) verfuegbarerZustand = "verfuegbar"; // verfuegbarer Zuatand = Geld kann abgehoben werden( d.h. PIN korrekt) maxBetrag = 1000 ; } public void karte_einwerfen (){ zustand = bereiterZustand ; System.out.println("Karte erhalten. Automat ist startbereit.") ; } public void pin_eingeben (String PIN ){ if (zustand == "bereit") if (PIN =="123") { bereiterZustand = verfuegbarerZustand ; System.out.println("PIN ist korrekt. Nun koennen sie ihr Geld abheben"); } if (PIN !="123") { bereiterZustand = zustand ; System.out.println("PIN ist falsch. Der Vorgang wird abgebrochen. Ihre Karte wird ausgegeben."); } if (zustand == "standby") { System.out.println("Bitte Karte einwerfen!"); } } public void abzuhebendenBetrag_waehlen (int Geldbetrag) { int maxBetrag = 1000; if (verfuegbarerZustand == "verfuegbar" ) { if (Geldbetrag <= maxBetrag){ neuesGuthaben = guthaben - Geldbetrag ; guthaben = neuesGuthaben ; System.out.println("Der Geldbetrag wurde abgehoben. Wollen sie noch mehr Geld abheben? ."); } else { System.out.println("Der eingegebene Betrag überschreitet das Maximale!") ; } } else { System.out.println("Bitte Karte bzw. PIN eingeben.") ; } } public void karte_ausgeben () { if (zustand == "bereit") { bereiterZustand = zustand ; System.out.println("Vorgang abgebrochen. Ihre Karte wird ausgegeben"); } if (zustand == "verfuegbar") { verfuegbarerZustand = zustand ; System.out.println("Vorgang abgebrochen. Ihre Karte wird ausgegeben"); } } } Bearbeitet 19. Dezember 2010 von flashpixx Code-Tags Zitieren
Klotzkopp Geschrieben 19. Dezember 2010 Geschrieben 19. Dezember 2010 Warum hast du mehrere Zustandsvariablen? Zitieren
Senf Geschrieben 19. Dezember 2010 Autor Geschrieben 19. Dezember 2010 Warum hast du mehrere Zustandsvariablen? Der Zustand "zustand" soll bedeuten dass der Automat noch keine Karte erhalten hat , und somit keine Aktion durchfueren kann Zustand "bereiterZustand bedeutet dass er die Karte erhalten hat und jetzt der PIN eingegeben werden kann. Zustand "verfuegbarer Zustand heisst dass der PIN richtig eingegeben wurde und somit Geld abgehoben werden kann. Kann ich das auch alles mit einem Zustand machen? Zitieren
flashpixx Geschrieben 19. Dezember 2010 Geschrieben 19. Dezember 2010 Verwende bitte das nächste Mal die Code-Tags. Die Zustände sollten, da sie eindeutig sind, als Enum abgelegt werden und nicht als Strings Zitieren
Klotzkopp Geschrieben 19. Dezember 2010 Geschrieben 19. Dezember 2010 Der Zustand "zustand" soll bedeuten dass der Automat noch keine Karte erhalten hat , und somit keine Aktion durchfueren kann Zustand "bereiterZustand bedeutet dass er die Karte erhalten hat und jetzt der PIN eingegeben werden kann. Zustand "verfuegbarer Zustand heisst dass der PIN richtig eingegeben wurde und somit Geld abgehoben werden kann.Das heißt, dein Automat ist gleichzeitig in drei Zuständen? Oder warum machst du das mit drei Variablen? Zitieren
Senf Geschrieben 19. Dezember 2010 Autor Geschrieben 19. Dezember 2010 Das heißt, dein Automat ist gleichzeitig in drei Zuständen? Oder warum machst du das mit drei Variablen? Nein, mein Automat soll die Zustaende wechseln. Hab ich da etwas falsch gemacht? Zitieren
Senf Geschrieben 19. Dezember 2010 Autor Geschrieben 19. Dezember 2010 Verwende bitte das nächste Mal die Code-Tags. Die Zustände sollten, da sie eindeutig sind, als Enum abgelegt werden und nicht als Strings Und wie sollte dies an Aussehen? ich kenne den Typ Enum nicht Zitieren
flashpixx Geschrieben 19. Dezember 2010 Geschrieben 19. Dezember 2010 Und wie sollte dies an Aussehen? ich kenne den Typ Enum nicht Enum Types (The Javaâ„¢ Tutorials > Learning the Java Language > Classes and Objects) Zitieren
Senf Geschrieben 19. Dezember 2010 Autor Geschrieben 19. Dezember 2010 Enum Types (The Javaâ„¢ Tutorials > Learning the Java Language > Classes and Objects) Vielen Dank fuer diesen Link. Nur glaube ich nicht das mir das etwas bringen wird.Wir haben bis jetzt noch nie mit dem Typ Enum gearbeitet. Unser Thema lautet "Zustandsuebergaenge mit Bedingungen". Die Zustaende sollte irgendwie automatisch wechseln. Können Sie mir noch ein paar Tips geben bitte? Zitieren
Senf Geschrieben 19. Dezember 2010 Autor Geschrieben 19. Dezember 2010 (bearbeitet) OK ich habe die Fehler beheben koennen, nun sieht es so aus public class Geldautomat { private int guthaben ; private int neuesGuthaben ; private int Geldbetrag ; private int maxBetrag ; private String PIN ; private String zustand ; private String verfuegbarerZustand ; private String bereiterZustand ; public Geldautomat() { guthaben = 10000 ; PIN = "123"; zustand = "standby" ; bereiterZustand = "bereit" ; //bereiterZustand = PIN kann eingegeben werden (d.h. Karte erhalten) verfuegbarerZustand = "verfuegbar"; // verfuegbarerZuatand = Geld kann abgehoben werden.(d.h PIN wurde korrekt eingegebe maxBetrag = 1000 ; } public void karte_einwerfen (){ zustand = bereiterZustand ; System.out.println("Karte erhalten. Automat ist startbereit.") ; } public void pin_eingeben (String PIN ){ if (zustand.equals("bereit")) if (PIN.equals("123")) { zustand = verfuegbarerZustand ; System.out.println("PIN ist korrekt. Nun koennen sie ihr Geld abheben"); } else { bereiterZustand = zustand ; System.out.println("PIN ist falsch. Der Vorgang wird abgebrochen. Ihre Karte wird ausgegeben."); } if (zustand.equals ("standby")) { System.out.println("Bitte Karte einwerfen!"); } } public void abzuhebendenBetrag_waehlen (int Geldbetrag) { if (zustand.equals ("verfuegbar") ) { if (Geldbetrag <= maxBetrag){ neuesGuthaben = guthaben - Geldbetrag ; guthaben = neuesGuthaben ; System.out.println("Der Geldbetrag wurde abgehoben. Wollen sie noch mehr Geld abheben? ."); } else { System.out.println("Der eingegebene Betrag überschreitet das Maximale!") ; } } else { System.out.println("Bitte Karte bzw. PIN eingeben.") ; } } public void karte_ausgeben () { if (zustand.equals ("bereit")) { bereiterZustand = zustand ; System.out.println("Vorgang abgebrochen. Ihre Karte wird ausgegeben"); } if (zustand.equals("verfuegbar")) { verfuegbarerZustand = zustand ; System.out.println("Vorgang abgebrochen. Ihre Karte wird ausgegeben"); } } } Bearbeitet 19. Dezember 2010 von Senf Zitieren
Klotzkopp Geschrieben 19. Dezember 2010 Geschrieben 19. Dezember 2010 Ich würde die Zustände anders benennen. Für mich ist "standby", "bereit" und "verfügbar" ungefähr gleichbedeutend. Ich könnte jedenfalls daraus nicht ohne weitere Informationen erkennen, in welchem Zustand der Automat ist. public void karte_ausgeben () { if (zustand.equals ("bereit")) { bereiterZustand = zustand ; System.out.println("Vorgang abgebrochen. Ihre Karte wird ausgegeben"); } if (zustand.equals("verfuegbar")) { verfuegbarerZustand = zustand ; System.out.println("Vorgang abgebrochen. Ihre Karte wird ausgegeben"); } }[/code]Das ist Käse. Die Zuweisungen an bereiterZustand und verfuegbarerZustand sind Unsinn, denn das, was du da zuweist, sollte sowieso schon drinstehen. Mir ist immer noch nicht klar, wozu du diese beiden Variablen überhaupt brauchst. Andererseits fehlt hier eine Zuweisung an zustand. Bei dieser Methode ändert sich also der Zustand deines Automaten nicht, d.h. nach Auswerfen der Karte ist der Automat immer noch bereit bzw. verfügbar. Zitieren
Senf Geschrieben 19. Dezember 2010 Autor Geschrieben 19. Dezember 2010 (bearbeitet) Koennen Sie mir erklaeren wie ich es mit einem Zustand programmieren kann? Das Geld soll nämlich nicht abgehoben werden, bevor die Karte eingeworfen und der PIN eingegben ist. Andererseits fehlt hier eine Zuweisung an zustand Was muss ich hier tun? public void karte_ausgeben () { if (zustand.equals ("bereit")) { bereiterZustand = zustand ; zustand = "standby" ; System.out.println("Vorgang abgebrochen. Ihre Karte wird ausgegeben"); } if (zustand.equals("verfuegbar")) { verfuegbarerZustand = zustand ; zustand = "standby" ; System.out.println("Vorgang abgebrochen. Ihre Karte wird ausgegeben"); } Ist das korrekt? Sollte ich zb verfuegbarerZustand = zustand ; schon in den Konstruktor mit einbringen? Bearbeitet 19. Dezember 2010 von Senf Zitieren
Klotzkopp Geschrieben 19. Dezember 2010 Geschrieben 19. Dezember 2010 Koennen Sie mir erklaeren wie ich es mit einem Zustand programmieren kann?Nicht mit einem Zustand. Mit einer Zustandsvariable. Drei Zustände sind schon ganz richtig. Warum hast du zusätzliche Variablen für zwei der drei Zustände? Was repräsentiert die Variable zustand? Antwort: Den Zustand des Automaten. Was repräsentiert die Variable bereiterZustand? Antwort: ? Was repräsentiert die Variable verfuegbarerZustand? Antwort: ? Wenn diese Variablen nur als "Platzhalter" existieren, damit du nicht mit den Stringliteralen arbeiten musst (was sogar einigermaßen sinnvoll wäre, da du damit Schreibfehler vermeiden kannst, aber Enums wären noch besser), warum benutzt du sie dann nicht auch in den Vergleichen, und warum gibt es keine solche Variable für den Standby-Zustand? Ist das korrekt?Das ist schon besser. Die Zuweisungen an bereiterZustand und verfuegbarerZustand sind nach wie vor komplett überflüssig. Sollte ich zb verfuegbarerZustand = zustand ; schon in den Konstruktor mit einbringen?Was soll das bewirken? Erklär doch bitte mal, wozu diese Variablen gut sein sollen. Zitieren
Senf Geschrieben 19. Dezember 2010 Autor Geschrieben 19. Dezember 2010 Warum hast du zusätzliche Variablen für zwei der drei Zustände? Was repräsentiert die Variable zustand? Antwort: Den Zustand des Automaten. Was repräsentiert die Variable bereiterZustand? Antwort: ? Was repräsentiert die Variable verfuegbarerZustand? Antwort: ? Ich habe mir dabei folgendes gedacht. zustand beschreibt den Zustand des Automaten, wenn die Karte noch nicht eingeworfen ist. bereiterZustand beschreibt den Zustand des Automaten, wenn die Karte eingeworfen wurde und der PIN eingegeben werden kann. verfuegbarerZustand beschreibt den Zustand des Automaten, wenn die Karte eingeworfen wurde und die PIN korrekt eingegeben wurde. Dann kann nämlich das Geld abgehoben werden. Für mich kling es logisch, aber womöglich ist es voelliger Schwachsinn. Sollte ich etwa im Konstruktor folgendes schreiben: zustand="standby" zustand="bereit" zustand="verfuegbar"? Aber das wäre doch völlig verkehrt oder? Vielen Dank dass Sie mir helfen Zitieren
flashpixx Geschrieben 19. Dezember 2010 Geschrieben 19. Dezember 2010 Mach doch das ganze auf einem Stück Papier. Deterministischer endlicher Automat ? Wikipedia findest Du die entsprechenden Diagramme, d.h. Du beschreibst den kompletten Automaten als solches Diagramm und wenn das vollständig ist, dann programmierst Du das ganze Zitieren
Senf Geschrieben 19. Dezember 2010 Autor Geschrieben 19. Dezember 2010 Ich habe bereits ein Zustandsübergangsdiagramm gemacht. Meine Programmierung sieht nun folgendermasen aus und ich denke sie ist vollstaendig und korrekt : public class Geldautomat { private int guthaben ; private int neuesGuthaben ; private int Geldbetrag ; private int maxBetrag ; private String PIN ; private String zustand ; public Geldautomat() { guthaben = 10000 ; PIN = "123"; zustand = "standby" ; zustand = "bereit" ; // bereit = Karte wurde eingeworfen => PIN kann eingegeben werden. zustand = "verfuegbar" ; //verfuegbar= Karte eingeworfen+richtiger PIN => Geld kann abgehoben werden maxBetrag = 1000 ; } public void karte_einwerfen (){ System.out.println("Karte erhalten. Automat ist startbereit.") ; zustand = "bereit" ; } public void pin_eingeben (String PIN ){ if (zustand.equals("bereit")) if (PIN.equals("123")) { System.out.println("PIN ist korrekt. Nun koennen sie ihr Geld abheben"); zustand = "verfuegbar" ; } else { System.out.println("PIN ist falsch. Der Vorgang wird abgebrochen. Ihre Karte wird ausgegeben."); zustand = "standby" ; } if (zustand.equals ("standby")) { System.out.println("Bitte Karte einwerfen!"); } } public void betrag_abheben (int Geldbetrag) { if (zustand.equals ("verfuegbar") ) { if (Geldbetrag <= maxBetrag){ neuesGuthaben = guthaben - Geldbetrag ; guthaben = neuesGuthaben ; System.out.println("Der Geldbetrag wurde abgehoben. Wollen sie noch mehr Geld abheben?"); } else { System.out.println("Der eingegebene Betrag überschreitet das Maximale!") ; } } else { System.out.println("Bitte Karte bzw. PIN eingeben.") ; } } public void karte_ausgeben () { if (zustand.equals ("bereit")) { zustand = "standby" ; System.out.println("Vorgang abgebrochen. Ihre Karte wird ausgegeben"); } if (zustand.equals("verfuegbar")) { zustand = "standby" ; System.out.println("Vorgang abgebrochen. Ihre Karte wird ausgegeben"); } } } Zitieren
flashpixx Geschrieben 19. Dezember 2010 Geschrieben 19. Dezember 2010 zustand = "standby" ; zustand = "bereit" ; // bereit = Karte wurde eingeworfen => PIN kann eingegeben werden. zustand = "verfuegbar" ; //verfuegbar= Karte eingeworfen+richtiger PIN => Geld kann abgehoben werden Das ist völlig sinnfrei, denn Du setzt den Zustand drei Mal und nachdem die Klasse instanziert wurde, ist der Automat im Zustand "verfuegbar". Die beiden vorhergehenden Zeilen sind überflüssig. Weiterhin enthält die Methode "karte_einwerfen" keine Zustandsprüfung. Ein dea muss immer in einem Zustand sein, d.h. Du musst sicherstellen, in welchem Zustand Du Dich befindest. Zitieren
Senf Geschrieben 19. Dezember 2010 Autor Geschrieben 19. Dezember 2010 Das ist völlig sinnfrei, denn Du setzt den Zustand drei Mal und nachdem die Klasse instanziert wurde, ist der Automat im Zustand "verfuegbar". Die beiden vorhergehenden Zeilen sind überflüssig. Was soll ich stattdessen machen? Weiterhin enthält die Methode "karte_einwerfen" keine Zustandsprüfung. Ein dea muss immer in einem Zustand sein, d.h. Du musst sicherstellen, in welchem Zustand Du Dich befindest. Sieht es so richtig aus: public void karte_einwerfen (){ if (zustand.equals("standby")){ System.out.println("Karte erhalten. Automat ist startbereit.") ; zustand = "bereit" ; } } Zitieren
Klotzkopp Geschrieben 19. Dezember 2010 Geschrieben 19. Dezember 2010 Was soll ich stattdessen machen?Welchen Zustand hat dein Automat denn am Anfang? Sieht es so richtig aus:Ja, das sieht gut aus. Du könntest im else-Fall noch eine Fehlermeldung ausgeben. Zitieren
Senf Geschrieben 19. Dezember 2010 Autor Geschrieben 19. Dezember 2010 Welchen Zustand hat dein Automat denn am Anfang? 1.Zustand Zu Beginn ist der automat auf Standby also keine Karte ist eingworfen 2.Zustand >>>Karte einwerfen Dann sollte es den Zustand wechseln wenn man die Karte eingeworfen hat. 3 Zustand >>>>PIN eingeben Als nächstes sollte der Zustand wechseln wenn der PIN eingebene ist und man das Geld abheben kann. Wäre es denn so richtig: Attribute und Konstruktor: public class Geldautomat { private int guthaben ; private int neuesGuthaben ; private int Geldbetrag ; private int maxBetrag ; private String PIN ; private String zustand1 ; private String zustand2 ; private String zustand3 ; public Geldautomat() { guthaben = 10000 ; PIN = "123"; zustand1 = "standby" ; zustand2 = "bereit" ; // bereit = Karte wurde eingeworfen => PIN kann eingegeben werden. zustand3 = "verfuegbar" ; //verfuegbar= Karte eingeworfen+richtiger PIN => Geld kann abgehoben werden maxBetrag = 1000 ; } Zitieren
Klotzkopp Geschrieben 19. Dezember 2010 Geschrieben 19. Dezember 2010 1.Zustand Zu Beginn ist der automat auf Standby also keine Karte ist eingworfenDann ist das auch den Zustand, den du im Konstruktor setzen solltest. Wäre es denn so richtig:Nein. Was willst du immer mit den zusätzlichen Variablen? Soll dein Automat 3 Zustände gleichzeitig annehmen, dass du 3 Variablen brauchst? Zitieren
Senf Geschrieben 19. Dezember 2010 Autor Geschrieben 19. Dezember 2010 Nein. Was willst du immer mit den zusätzlichen Variablen? Soll dein Automat 3 Zustände gleichzeitig annehmen, dass du 3 Variablen brauchst? Nein ich will das der Automat 3 verschiedene Zustaende annehemn kann. Können sie mir sagen wie ich das machen muss? Zitieren
Klotzkopp Geschrieben 19. Dezember 2010 Geschrieben 19. Dezember 2010 Nein ich will das der Automat 3 verschiedene Zustaende annehemn kann.Der Automat hat zu jedem Zeitpunkt genau einen Zustand. Er kann nicht alle drei Zustände gleichzeitig annehmen. Darum reicht auch eine Variable, die je nach aktuellem Zustand einen anderen Wert annimmt. Zitieren
Senf Geschrieben 19. Dezember 2010 Autor Geschrieben 19. Dezember 2010 (bearbeitet) Der Automat hat zu jedem Zeitpunkt genau einen Zustand. Er kann nicht alle drei Zustände gleichzeitig annehmen. Darum reicht auch eine Variable, die je nach aktuellem Zustand einen anderen Wert annimmt. Wo und wie gebe ich der Varible verschiedene Werte? Koennten Sie mir dies bitte bei meinem Beispiel erklaeren? Nachtrag: Ich glaube so ist es richtig: Der Automat funktioniert einwandfrei, koennten Sie trozdem nochmal einen Blick drauf werfen? public class Geldautomat { private int guthaben ; private int neuesGuthaben ; private int Geldbetrag ; private int maxBetrag ; private String PIN ; private String zustand ; public Geldautomat() { guthaben = 10000 ; PIN = "123"; zustand = "standby" ; maxBetrag = 1000 ; } public void karte_einwerfen (){ System.out.println("Ihre Karte wurde eingegeben.") ; zustand = "bereit" ; } public void pin_eingeben (String PIN ){ if (zustand.equals("bereit")) if (PIN.equals("123")) { System.out.println("PIN ist korrekt. Nun koennen sie ihr Geld abheben"); zustand = "verfuegbar" ; } else { System.out.println("PIN ist falsch. Der Vorgang wird abgebrochen. Ihre Karte wird ausgegeben."); zustand = "standby" ; } if (zustand.equals ("standby")) { System.out.println("Bitte Karte einwerfen!"); } } public void betrag_abheben (int Geldbetrag) { if (zustand.equals ("verfuegbar") ) { if (Geldbetrag <= maxBetrag){ neuesGuthaben = guthaben - Geldbetrag ; guthaben = neuesGuthaben ; System.out.println("Der Geldbetrag wurde abgehoben. Wollen sie noch mehr Geld abheben?"); } else { System.out.println("Der eingegebene Betrag überschreitet das Maximale!") ; } } else { System.out.println("Bitte Karte bzw. PIN eingeben.") ; } } public void karte_ausgeben () { if (zustand.equals ("bereit")) { zustand = "standby" ; System.out.println("Vorgang beendet. Ihre Karte wird ausgegeben"); } if (zustand.equals("verfuegbar")) { zustand = "standby" ; System.out.println("Vorgang beendet. Ihre Karte wird ausgegeben"); } } } Bearbeitet 19. Dezember 2010 von Senf Zitieren
Klotzkopp Geschrieben 19. Dezember 2010 Geschrieben 19. Dezember 2010 Das sieht ganz gut aus. Du kannst noch die Instanzvariablen neuesGuthaben, Geldbetrag und PIN rauswerfen. Geldbetrag und PIN werden nie benutzt, sondern nur von den gleichnamigen Parametern verdeckt. neuesGuthaben speichert nur ein Zwischenergebnis, das kann man besser mit einer lokalen Variablen machen, oder die Rechnung gleich in einem Schritt durchführen. Zitieren
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.