Ergebnis 1 bis 11 von 11

Thema: [Tutorial] Java #3 - Kontrolle ist wichtig

  1. #1

    [Tutorial] Java #3 - Kontrolle ist wichtig

    Einleitung
    Da DFYX das Java Tutorial nicht vollständig allein schreiben soll, dachte ich mir ich schreibe
    mal den dritten Teil. Der letzte Teil beschäftigte sich mit Variablen und ihrer grundlegenden Verwendung.
    Daher ist es nun sinnvoll sich mit den sogenannten Kontrollstrukturen zu beschäftigen.

    Quellcodebeispiele werden ohne die Main Methode und ohne die Klasse drumherum gezeigt. Ich gehe nach den letzten Tutorials davon
    aus das man als Leser weiß, das der gezeigte Beispielcode in eine solche gehört damit er überhaupt ausgeführt wird.
    Code (JAVA):
     
    1.	public class Uebung{
    2.		public static void main(String[] args) {
    3.			// Hier kommt der ausfuehrbare Code hinein
    4.		}
    5.	}
     



    Entscheidungen sind nötig...
    In unserem Alltag sind Entscheidungen an allen Ecken und Enden nötig. Simples Beispiel aus dem Alltag
    was nun jeder kennt: eine Ampel. Man steht vor einer Straße und anderen Straßenseite ist eine Ampel.
    Man hat zum einen die Information das man nur über die Straße gehen soll wenn die Ampel auf grün steht,
    ansonsten soll man warten.
    Je nachdem ob die Ampel auf Rot oder auf Grün ist, überquert man die Straße oder wartet bis sie auf grün schaltet.
    Anhand von diesem Beispiel kann man nun gut unsere erste Kontrollstruktur vorstellen, die Bedingung.

    Zuerst einmal brauchen wir etwas in das wir abspeichern können ob unsere Ampel auf rot oder grün steht.
    Wir haben also zwei Zustände die sie erreichen kann. Da bietet sich ein boolean an, da dieser
    die zwei Zustände true(Ampel grün) und false(Ampel rot) speichern kann.

    Code (JAVA):
    1.    boolean ampelstatus = false;


    Wir deklarieren uns also eine Boolean Variable und initialisieren sie direkt mit dem Wert "false". Unsere Ampel
    steht also von Anfang an erstmal auf rot.

    Nun brauchen wir etwas um zu überprüfen auf welchen Status unsere Variable gerade ist. Dafür bietet
    Java uns die Bedingung an.

    Code (JAVA):
     
    1.	// Syntax einer Bedingung
    2.	if(bedingung){
    3.	  // Code hier drin wird nur ausgeführt wenn die Bedingung erfüllt(wahr) ist
    4.	}
     


    Nur wenn die Bedingung die im Kopf steht erfüllt ist, wird der dahinter liegende Anweisungsblock ausgeführt.
    Der Anfang eines Blockes wird durch eine einleitende { angezeigt und durch
    ein abschließendes } beendet.

    Die Bedingung muss in unserem Fall sein ob die Ampel Grün ist. Also setzen wir es um:

    Code (JAVA):
     
    1.	if(ampelstatus == true){ // Ampel ist gruen
    2.	    System.out.println("Die Ampel ist gruen!");
    3.	}
     


    Mit dem == Operatoren führt man in Java Vergleiche durch.
    Verwechsele das nicht mit dem = Operator, der ist dazu da einer Variable einen Wert zuzuweisen.

    Nun haben wir allerdings noch das Problem das wir ja auch anzeigen wollen ob die Ampel auf rot steht.
    Gut, also noch eine Bedingung.

    Code (JAVA):
     
    1.	if(ampelstatus == true){ // Ampel ist gruen
    2.	    System.out.println("Die Ampel ist gruen!");
    3.	}
    4.	if(ampelstatus == false){ // Ampel ist rot
    5.	    System.out.println("Die Ampel ist rot!");
    6.	}
     


    Soweit so gut. Aber irgendwie ist die Lösung nicht ganz das wahre. Jetzt muss Java ja beide
    Bedingungen durchlaufen, obwohl immer nur eine wahr sein kann. Immerhin ist eine Ampel nur rot oder grün.
    Nie beides gleichzeitig. Aber kein Problem, dafür hat die Bedingung etwas parat.

    Code (JAVA):
     
    1.	if(ampelstatus == true){ // Ampel ist gruen
    2.	    System.out.println("Die Ampel ist gruen!");
    3.	}else{ 			 // Ampel ist rot
    4.	    System.out.println("Die Ampel ist rot!");
    5.	}
     


    Was ist hier neu? Richtig, das else. Dieser sogenannte "Else-Zweig" wird nun immer dann ausgeführt
    wenn die Bedingung nicht erfüllt ist. Da unsere boolean Variable aber nur true oder false sein kann,
    stört uns das in diesem Fall nicht weiter und ist damit genau das was wir brauchen. In anderen Fällen sollte man darauf
    jedoch achten.

    Unsere komplette Ampel:

    Code (JAVA):
     
    1.	boolean ampelstatus = false;
    2.        
    3.	if(ampelstatus == true){ // Ampel ist gruen
    4.	    System.out.println("Die Ampel ist gruen!");
    5.	}else{ 			 // Ampel ist rot
    6.	    System.out.println("Die Ampel ist rot!");
    7.	}
     


    Ausgabe wenn ampelstatus auf true steht
    Code:
    Die Ampel ist gruen!
    Ausgabe wenn ampelstatus auf false steht
    Code:
    Die Ampel ist rot!
    Bedingungen sind also dafür gut um je nachdem auf welchem Wert eine Variable eine andere Folge von Befehlen auszuführen.
    Sie lassen sich im übrigen auch schachteln:

    Code (JAVA):
     
    1.  int zahl = 2;
    2.  int zahl2 = 2;
    3.  
    4.  if(zahl == 1){
    5.      System.out.println("zahl ist auf 1!");
    6.  }else if(zahl == zahl2){
    7.      System.out.print("zahl und zahl2 stehen beide auf demselben Wert ! zahl: ");
    8.      System.out.print(zahl);
    9.  }else{
    10.     System.out.println("zahl steht auf irgendeinem anderen Wert als gedacht.");
    11. }
     


    Erklärung:
    In Zeile 1 und 2 werden nur zwei integer Variablen deklariert und mit dem Wert 2 initalisiert.
    in Zeile 4 wird dann auf die Bedingung geprüft ob die Variable zahl auf 1 steht, wenn sie das tut
    wird der Text "zahl ist auf 1!" ausgegeben. (Zeile 5)
    Wenn zahl nicht auf 1 steht, wird der Alternative else Zweig in Zeile 6 abgearbeitet der dann die Bedingung prüft
    ob zahl denselben Inhalt hat wie zahl2. Wenn ja, dann wird in Zeile 7 erstmal der Text "zahl und zahl2 stehen beide auf demselben Wert ! zahl: "
    ausgegeben und in Zeile 8 der Inhalt der Variable zahl.
    Falls nun beide Bedingung nun nicht erfüllt worden sind, wird der letzte mögliche Zweig in Zeile 9 ausgeführt,
    wodurch die Ausgabe "zahl steht auf irgendeinem anderen Wert als gedacht." in Zeile 10 ausgelöst wird.

    Wir haben ja nun zwei Werte bei unseren Variablen voreingestellt. Wie sieht denn die Ausgabe des erklärten Programmes aus?
    Denk kurz darüber nach und öffnet dann den Spoiler.


    Was bei zuvielen Entscheidungen?
    Bedingungen sind nützliche Mittel um Verzweigungen im Quellcode umzusetzen. Was aber nun tun wenn man viele Entscheidungen abfragen muss? Ein IF-Else Konstrukt kann dabei schnell unübersichtlich werden. Zu diesem Zweck existiert die Anweisung "Switch".

    Code (JAVA):
     
    // Syntax eines Switches
    switch(variable){
    	case [wert]: [Anweisungen]
    }
     


    Der Switch ist dabei so angelegt das man eine Reihe von Fällen prüft.
    Hinter dem "case"(Fall) wird auf einen Wert geprüft, der in der Variable die wir in den runden Klammern
    hinter dem "switch" Schlüssel angegeben haben, stehen könnte. Falls ein Fall zutrifft, werden die Anweisungen
    ausgeführt die hinter dem Doppelpunkt stehen. Klingt kompliziert? Ist es an sich nicht, das kleine Praxisbeispiel
    macht es denke ich klarer:

    Code (JAVA):
     
    1.        int monat = 12;
    2.
    3.        switch(monat){
    4.            case 1: System.out.println("Januar"); break;
    5.            case 2: System.out.println("Februar"); break;
    6.            case 3: System.out.println("Maerz"); break;
    7.            case 4: System.out.println("April"); break;
    8.            case 5: System.out.println("Mai"); break;
    9.            case 6: System.out.println("Juni"); break;
    10.           case 7: System.out.println("Juli"); break;
    11.           case 8: System.out.println("August"); break;
    12.           case 9: System.out.println("September"); break;
    13.           case 10: System.out.println("Oktober"); break;
    14.           case 11: System.out.println("November"); break;
    15.           case 12: System.out.println("Dezember"); break;
    16.           default: System.out.println("Kein Monat fuer diese Zahl!");
    17.       }
     


    Je nachdem welche Zahl im Integer "monat" steht, wird ein anderer Fall ausgeführt. Im Beispiel steht eine 12 in unserer Variable,
    also wird man als Ausgabe erhalten:
    Code:
    Dezember
    Das "break;" hinter der letzten Anweisung in einem Fall ist wichtig, damit der Switch an dieser Stelle abgebrochen wird.
    Ohne diesen Befehl, würden dann noch weitere Fälle durchgegangen werden, bis der Switch zuende ist oder bis ein break auftritt.
    Der abschließende "Default"-Fall ist die Ausnahmebedingung die ausgeführt wird, falls keiner der vorangegangen Fälle erfüllt worden ist.
    Das wäre in unserem Beispiel der Fall wenn man z.B. eine 13 in unsere Variable speichert.

    Schlusswort
    Damit haben wir zwei wichtige Kontrollstrukturen abgedeckt. Es fehlen natürlich noch welche, nur soll das Tutorial erstmal nicht zu lang werden. Als nächstes wären Schleifen eine gute Fortsetzung. Diese Tutorial ist vom Code her absichtlich meist etwas ausführlicher geschrieben als nötig, da es ja der Erklärung dienen soll. Sicherlich lässt sich so mancher Code hier kürzer schreiben. Eine Aufgabe stelle ich (noch) nicht, da dafür in meinen Augen erstmal noch etwas Wissen vorhanden sein sollte. Ich hoffe das Tutorial hilft ein wenig und es schreiben noch mehr mit.

    ~ Makenshi

    Geändert von makenshi (04.05.2010 um 13:54 Uhr)

  2. #2
    Sehr gutes Tutorium makenshi!
    Ich weiß nicht, könnte man noch hinzufügen, das bei einem boolean im If-Zweig nicht stehen muss "if(boolean == true) {}" sondern es schon reicht wenn man schreibt "if(boolean) {}"?

    Edit:
    Stimmt, einige bei uns hatten das auch nicht recht verstanden, ähnlich wie die foreach-schleife.

    Geändert von R.D. (04.05.2010 um 17:18 Uhr)

  3. #3
    Zitat Zitat von R.D. Beitrag anzeigen
    Sehr gutes Tutorium makenshi!
    Ich weiß nicht, könnte man noch hinzufügen, das bei einem boolean im If-Zweig nicht stehen muss "if(boolean == true) {}" sondern es schon reicht wenn man schreibt "if(boolean) {}"?
    Dankeschön.
    Ja, da würde reichen, es ist in meinen Augen aber eine Kurzschreibweise. Und solche wollte ich in einem Tutorial eher vermeiden. Darum der Hinweis im Schlusswort das ich manches absichtlich länger gehalten habe.

  4. #4
    naja, ich hab mir den Text nicht durchgelesen, sondern nur die Code-Schnippsel.
    Ich muss leider sagen, dass die Codes unglücklich gewählt worden sind.
    Beide Male sind das Fälle, wo ein Enum mehr Sinn gemacht hätte.

    Sicherlich, es ist nur ein Tutorial für Anfänger, aber gerade den Anfängern sollte man es doch zeigen, wie es richtig geht und wie man einen Code richtig und semantisch leserlich schreibt. Dazu gehören auch die Schreibweise, die du als "Kurzschreibweise" bezeichnest.
    Wenn ein Anfänger nicht versteht, dass in einer If-Anweisung nur ein Boolean-wert ausgewertet wird und es egal ist, ob da nun ein Vergleichsoperator steht, oder nicht, der hat einfach die If-Anweisung nicht verstanden.

    z.B.
    Code:
    if (Error) { ... }
    liest sich einfach besser als
    Code:
    if (Error == true) { ... }
    Sun (bzw. jetzt Oracle) hat für Java Programmierregeln aufgestellt, die man auch bestmöglich einhalten sollte. Die Case-Anweisung würde durch die Regeln durchfallen, da hier feste Zahlen im Spiel sind. Das ist, laut Programmierregeln, nicht erlaubt.

  5. #5
    Zitat Zitat
    Sun (bzw. jetzt Oracle) hat für Java Programmierregeln aufgestellt, die man auch bestmöglich einhalten sollte.
    Sind es nicht bewusst Empfehlungen statt Regeln?

    Zitat Zitat
    Die Case-Anweisung würde durch die Regeln durchfallen, da hier feste Zahlen im Spiel sind
    Wie wäre denn dann die von Sun präferierte Lösung dieses Statements? Ich bin da gerade etwas ratlos, ich habe diese Art von Code auch in Java schon oft gesehen ...

    Und was ich noch zum Ursprungspost sagen wollte: Nett geschrieben und meiner Meinung nach auch verständlich. Fortfahren würde ich aber nicht mit Schleifen, sondern mit Eingabemöglichkeitnen (über Scanner). Das hat den Charme, das man dann mit den schon vorgestellen Techniken (Ausgabe, Variablen, Kontrollstrukturen, Eingabe) Programme schreiben, die auch wirklich etwas tun und benutzbar sind. Zwar nur kleine Spielereien, aber ich glaube, wer diesen Kurs wirklich benutzt, um zu lernen, für den ist das viel wert. Womit ich mich auch ein bißchen frage: Liest eigentlich jemand diesen Kurs wirklich, um damit Java zu lernen oder lesen hier nur Leute mit, die das sowieso schon können?

  6. #6
    Zitat Zitat von Miau Beitrag anzeigen
    Wie wäre denn dann die von Sun präferierte Lösung dieses Statements? Ich bin da gerade etwas ratlos, ich habe diese Art von Code auch in Java schon oft gesehen ...
    Wie ich schon sagte: Enumerator (Aufzählungstyp).
    Enums sind eine Spezialklassse.
    Code:
    public enum Months {
      JANUARY, FEBRUARY, MARCH, APRIL, MAY, JUNE,
      JULY, AUGUST, SEPTEMBER, OCTOBER, NOVEMBER, DECEMBER
    }
    Java baut daraus automatisch eine eigene Klasse, die so aussieht

    Code:
    class Months extends Enum { 
      public static final Weekday JANUARY  = new Months( "JANUARY",   0 ); 
      public static final Weekday FEBRUARY = new Months( "FEBRUARY ", 1 ); 
      ... 
     
      private Months( String s, int i ) { 
        super( s, i ); 
      }
    }
    Dann würde die Case-Anweisung z.B. wie folgt aussehen:

    Code:
    Months month = Months.FEBRUARY;
    
    switch(month) {
      case JANUARY: ...
      case FEBRUARY: ...
      ...
    }
    Bei der Ampel würde das dann ähnlich aussehen. Nur dass wir hier drei werte im Enum haben: RED, YELLOW, GREEN

    Sowas lässt sich auch besser lesen als Zahlen.

  7. #7
    Was Enums sind, weiß ich. Allerdings nutzt Sun sie selbst oft nicht, wenn es angebracht wäre, z.B. bei vielen Swing-Sachen. Insofern wundert mich das etwas, dass sie das dann trotzdem vorschlagen. Kontanten (bzw. static final Variablen) sind auch nicht gerne gesehen?

  8. #8
    Enums wurden in Java, wenn ich mich da richtig erinnere, erst mit 1.5 eingeführt, deshalb ist natürlich Swing da größtenteils noch anders konstruiert.

    Nebenbei erwähnt: Mit Enums wird die Case-Abfrage sogar völlig sinnfrei, weil man das dann eleganter einfach dem Enum mitgeben kann. Das schöne an Enums ist ja, dass man damit mehr machen kann.

  9. #9
    @Whiz-zarD
    Du missverstehst vollständig und völlig den Sinn dieses Abschnittes.
    Es ging diesen Teil darum zwei Kontrollstrukturen vorzustellen. Sowohl die Bedingung als auch den Switch. Beides sind Sprachelemente die in Java vorhanden sind. Es ging mir demnach darum Anfängern diese zwei Sprachelemente näherzubringen.

    Es ging mir nicht darum zu erklären wie man am effektivsten eine Aufzählung der Monatsnamen darstellen. Das man für so etwas ein Enum nehmen kann ist klar. Nur hat ein Enum hier nunmal nichts zu suchen. Wenn du jemandem gerade erst bei gebracht hast wie er Variablen deklariert und initialisiert, kannst du nicht erwarten das er dir zu so einem Zeitpunkt schon soweit folgen kann.
    Die Sache mit den Monaten war also lediglich ein Beispiel um die Funktionalität des Switches zu erklären. Mehr nicht. Die Aussage das das die beste Methode sei sucht man nicht ohne Grund im Text vergeblich.

    Die Kurzschreibweise die du ansprichst nutze ich wie gesagt nicht da ich oft erlebt habe das sie erstmal für Verwirrung gesorgt hat. Wenn man sie im Nachhinein im Context mit einem Quellcode einstreut, wird sie zugleich besser verstanden als wenn man von vorn herein mit voller Streuung vorgeht. Eine Tutorialreihe sollte schon einen auf sich aufbauenden Lerneffekt haben. Den würde man so sprichwörtlich abtöten. Ein Anfänger der erstmal verstanden hat das er mit Bedingungen je nach Ergebnis seinen Codefluß steuern kann, hat erstmal genug verstanden. Der Rest kommt auch noch, Rom wurde immerhin auch nicht an einem Tag erbaut.

    Wirkt jetzt vielleicht so als würde ich deine Einwände einfach plattargumentieren, aber ich glaube einfach das du das ganze viel zu sehr aus deiner fortgeschrittenen Sicht siehst. Soweit ich diese Reihe sehe sollte sie an Anfänger gerichtet sein, nicht an Fortgeschrittene. Von mir aus Leute die bei null anfangen. Wenn du also diese Clientel als Leser siehst, kann man nicht so herangehen wie du es hier vorschlägst.


    @Miau
    Ja, die Scannerklasse ist definitiv eine gute Idee. Ich würde sie aber wohl im Zusammenhang mit den Schleifen quasi direkt "einführen". Für Objektorientierung sind wir noch am falschen Punkt. Heisst also mehr als ein: "So kannst du einlesen." würde das ohnehin erstmal nicht werden. In C++ Tutorials wird einem auf diese Art und Weise ja auch erstmal die Eingabe vor die Füße gelegt.

    Ein wirklich benutzbares Programm wäre als Aufgabe nach dem Schleifenteil sicherlich ne gute Idee. Dann kann ist dafür an sich erstmal genug Wissen vorhanden. Und es kann damit gleich der Test erfolgen ob das erworbene Wissen kombiniert werden kann.

  10. #10
    Zitat Zitat
    @Miau
    Ja, die Scannerklasse ist definitiv eine gute Idee. Ich würde sie aber wohl im Zusammenhang mit den Schleifen quasi direkt "einführen". Für Objektorientierung sind wir noch am falschen Punkt. Heisst also mehr als ein: "So kannst du einlesen." würde das ohnehin erstmal nicht werden. In C++ Tutorials wird einem auf diese Art und Weise ja auch erstmal die Eingabe vor die Füße gelegt.
    Ich würde auch komplett drauf verzichten, die genaue Funktionsweise und Bedeutung von Scanner zu erklären. Auch auf try-catch würde ich erstmal verzichten, nur wie man damit einliest (mit den nextXXX()-Methoden bzw. nur next() ), damit lässt sich dann schon was machen. Als Kapitelinhalt allein ist das vielleicht etwas dünn, aber in Kombination mit Schleifen vielleicht schon etwas viel ...

  11. #11
    Zitat Zitat von makenshi Beitrag anzeigen
    Wirkt jetzt vielleicht so als würde ich deine Einwände einfach plattargumentieren, aber ich glaube einfach das du das ganze viel zu sehr aus deiner fortgeschrittenen Sicht siehst. Soweit ich diese Reihe sehe sollte sie an Anfänger gerichtet sein, nicht an Fortgeschrittene. Von mir aus Leute die bei null anfangen. Wenn du also diese Clientel als Leser siehst, kann man nicht so herangehen wie du es hier vorschlägst.
    Die Zielgruppe ist wohl wirklich das wichtige. Ich mache nebenher Java-Tutorium für Studenten, die schon nen C-Kurs hatten und selbst da sollte man wohl eher so wie hier vorgehen. Bei erfahrenen Programmierern hingegen könnte man wohl gleich in solche Sachen reinspringen, Operatoren erklären, Enums beschreiben, etc. Aber das ist ja hier nicht der Fall.

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •