Benutzer-Werkzeuge

Webseiten-Werkzeuge


g9:uebungen:eigene_klassen:start

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Nächste Überarbeitung
Vorhergehende Überarbeitung
g9:uebungen:eigene_klassen:start [2021/01/20 12:54] – angelegt Martin Pabstg9:uebungen:eigene_klassen:start [2022/06/30 07:23] (aktuell) – [Zweite Erweiterung: Rückgabe des Würfelergebnisses] Martin Pabst
Zeile 1: Zeile 1:
 ====== Eigene Klassen mit Methoden und Attributen ====== ====== Eigene Klassen mit Methoden und Attributen ======
 +
 +===== Beispiel 1: Würfel-Klasse (Methoden mit Parametern und Rückgabewerten) =====
 +Wir wollen in den folgenden Abschnitten eine Klasse ''Würfel'' schreiben und stetig verbessern. Zunächst wünschen wir uns ein Würfel-Objekt, das eine Methode ''würfle'' besitzt, die eine Zahl zwischen 1 und 6 ausgibt. Sie soll also folgendermaßen verwendet werden können:
 +<code myjava>
 +   Würfel w = new Würfel();
 +   w.würfle();
 +</code>
 +
 +
 +<HTML>
 +
 +<div class="java-online" style="height: 300px; width: 100%" data-java-online="{'withBottomPanel': false, 'id': 'Wuerfel1'}">
 +
 +<script type="text/plain" title="Main1.java">
 +Würfel w = new Würfel();
 +w.würfle();
 +
 +class Würfel {
 +
 +   void würfle(){
 +      int zahl = Math.floor(Math.random() * 6) + 1;
 +      println(zahl);
 +   }
 +
 +}
 +
 +</script>
 +</div>
 +
 +</HTML>
 +
 +<WRAP center round info 60%>
 +** Definition einer Klasse** \\ 
 +Eine Klasse wird mit dem Schlüsselwort ''class'' definiert: 
 +<code myjava>
 +class Würfel {
 +   // Deklaration der Attribute
 +   // Deklaration der Methoden
 +}
 +</code>
 +Zwischen den ''  }'' werden die **Methoden** und **Attribute** der Klasse deklariert. \\ \\ 
 +**Deklaration einer Methode** \\ 
 +Eine Methode ohne Parameter und Rückgabewert (dazu weiter unten mehr) wird folgendermaßen deklariert:
 +<code myjava>
 +void würfle(){
 +   // Anweisungen
 +}
 +</code>
 +
 +
 +Zuerst wird der **Datentyp des Rückgabewertes** angegeben, in diesem Fall ''void'' [[https://dict.leo.org/englisch-deutsch/void|(engl: "Leere")]] für "Kein Rückgabewert". Es folgt der **Bezeichner** der Methode (hier: würfle) und ''()''. In die Klammern schreiben wir - falls benötigt - die **Deklaration der Parameter** (siehe weiter unten). Zwischen die ''  }'' kommen die **Anweisungen**, die ausgeführt werden sollen, wenn die Methode aufgerufen wird. Man spricht oft vom **Methodenrumpf** (engl.: method body).
 +</WRAP>
 +
 +
 +==== Erste Erweiterung: Übergabe der Seitenzahl als Parameter ====
 +Es gibt nicht nur 6-seitige Würfel, sondern auch 8-seitige, 20-seitige usw. Wir erweitern die Methode würfle so, dass beim Aufruf die Anzahl der Seiten des Würfels mit angegeben werden kann:
 +<code myjava>
 +   Würfel w = new Würfel();
 +   w.würfle(6);     // Würfle mit einem 6-seitigen Würfel und gib das Ergebnis aus
 +   w.würfle(20);    // Würfle mit einem 20-seitigen Würfel und gib das Ergebnis aus
 +</code>
 +<WRAP center round help 80%>
 +Wie bringen wir die Information darüber, wie viele Seiten der Würfel hat (oben: 6 bzw. 20) in die Methode und wie erreichen wir, dass diese Information dort berücksichtigt wird? \\ \\ 
 +Wir deklarieren einen **Parameter**!
 +</WRAP>
 +
 +<HTML>
 +
 +<div class="java-online" style="height: 300px; width: 100%" data-java-online="{'withBottomPanel': false, 'id': 'Wuerfel2'}">
 +
 +<script type="text/plain" title="Main2.java">
 +Würfel w = new Würfel();
 +w.würfle(20);
 +w.würfle(6);
 +
 +class Würfel {
 +
 +   void würfle(int seitenzahl){
 +      int zahl = Math.floor(Math.random() * seitenzahl) + 1;
 +      println(zahl);
 +   }
 +
 +}
 +
 +</script>
 +</div>
 +
 +</HTML>
  
 <WRAP center round info 80%> <WRAP center round info 80%>
-Die Schülerinnen und Schüler ... +Die **Parameter einer Methode** legen fest, welche Werte beim Aufruf der Methode an den Methodenrumpf übergeben werden, welche Datentypen sie besitzen und mit welchem Bezeichner sie innerhalb der Methode verwendet werden können\\ \\  
-  * analysieren Objekte aus ihrer Erfahrungswelt (zBFahrzeugePersonenhinsichtlich ihrer Eigenschaften (Attribute) und Fähigkeiten (Methoden) und abstrahieren sie zu Klassen. Sie stellen Objekte und Klassen als Grundlage einer möglichen Implementierung grafisch dar+''void würfle(int seitenzahl)'' deklariert die Methode ''würfle'' mit dem Parameter ''seitenzahl'' vom Datentyp ''int''Ruft man die Methode beispielsweise durch 
-  * deklarieren eine Klasse sowie die zugehörigen Attribute und Methoden in einer objektorientierten Programmiersprache+<code myjava> 
-  verwenden bei der Implementierung Wertzuweisungenum Attributwerte zu ändernund interpretieren diese als Zustandsänderung des zugehörigen Objekts.+w.würfle(20); 
 +</code> 
 +auf, so wird beim Aufruf eine Kopie des übergebenen Wertes in den Parameter ''seitenzahl'' geschrieben. Beim der nachfolgenden Berechnung des Terms 
 +<code myjava> 
 +   Math.floor(Math.random() * seitenzahl) + 1; 
 +</code> 
 +hat ''seitenzahl'' also den Wert 20. Wird die Methode später mit einem anderen Paramterwert aufgerufen, z.B. ''w.würfle(6);'', so wird beim Methodenaufruf eine Kopie //dieses// Wertes in den Parameter ''seitenzahl'' geschrieben.  \\ \\  
 +**Tipp:** \\  
 +Führe das obige Programm in Einzelschritten aus und beobachte bei jedem Schritt, ob der Parameter ''seitenzahl'' im Reiter "Variablen" sichtbar ist und welchen Wert er hat. Achte dabei darauf, beim Methodenaufruf **nicht** auf den Button "Step over" ({{:klassen1:anwenden:step_over.png?nolink|}}) zu klicken, sondern auf den Button **"Step into"** ({{:klassen1:eigene:step-into.png?nolink|}})Dieser bewirktdass die Methode nicht in einem Rutsch ausgeführt wird, sondern auch die Anweisungen im Methodenrumpf schrittweise abgearbeitet werden. 
 +</WRAP> 
 + 
 +==== Zweite Erweiterung: Rückgabe des Würfelergebnisses ==== 
 + 
 +Im Hauptprogramm soll 3-mal gewürfelt werden. Anschließend soll die Summe der Augenzahlen ausgegeben werden.  
 + 
 +<WRAP center round tip 80%> 
 +Wir brauchen also eine Möglichkeit, die gewürfelte Augenzahl von der Methode ''würfle'' ins Hauptprogramm zu übertragen um dort die Summe zu berechnen. 
 +</WRAP> 
 + 
 +<HTML> 
 + 
 +<div class="java-online" style="height: 300px; width: 100%" data-java-online="{'withBottomPanel': false, 'id': 'Wuerfel2'}"> 
 + 
 +<script type="text/plain" title="Main3.java"> 
 +Würfel w = new Würfel()
 +int summe = w.würfle(6+ w.würfle(6) + w.würfle(6);     // 3-mal würfeln und Summe berechnen 
 +println("Summe aus drei Würfen: " + summe);  
 + 
 +class Würfel { 
 + 
 +   int würfle(int seitenzahl){ 
 +      int zahl = Math.floor(Math.random() * seitenzahl) + 1; 
 +      return zahl; 
 +   } 
 + 
 +
 + 
 +</script> 
 +</div> 
 + 
 +</HTML> 
 + 
 +<WRAP center round info 80%> 
 +Mit Hilfe der ''return''-Anweisung kann eine Methode einen Wert an die aufrufende Stelle zurückgeben. Der Datentyp wird bei der Deklaration der Methode vor dem Methodenbezeichner angegeben, z.B.  
 +<code myjava> 
 +int würfle(int seitenzahl){ ... } 
 +</code> 
 + 
 +Methoden, die einen Wert zurückgeben, nennt man oft auch **Funktionen**. 
 +</WRAP> 
 + 
 +===== Beispiel 2: Rechner-Klasse (mehrere Parameter===== 
 +Wir schreiben eine Klasse Rechner mit Methoden ''summe'', ''differenz'' und ''potenz'' und berechnen damit $2^3 + 5$. 
 + 
 +<HTML> 
 + 
 +<div class="java-online" style="height: 500px; width: 100%" data-java-online="{'withBottomPanel': false, 'id': 'Rechner1'}"> 
 + 
 +<script type="text/plain" title="Main4.java"> 
 +Rechner r = new Rechner(); 
 +println(r.summe(r.potenz(2, 3), 5)); 
 + 
 +class Rechner { 
 +   double summe(double summand1, double summand2) { 
 +      return summand1 + summand2; 
 +   } 
 + 
 +   double differenz(double minuend, double subtrahend) { 
 +      return minuend - subtrahend; 
 +   } 
 + 
 +   double potenz(double basis, int exponent) { 
 +      double ergebnis = 1; 
 +      for(int i = 0; i < exponent; i++) { 
 +         ergebnis = ergebnis * basis; 
 +      } 
 +      return ergebnis; 
 +   } 
 +
 +</script> 
 +</div> 
 + 
 +</HTML> 
 + 
 +<WRAP center round info 80%> 
 +**Methoden mit mehreren Parametern** \\ \\  
 +Methoden können auch mehrere Parameter haben. Sie werden einfach mit Komma getrennt hintereinander deklariert, z.B. 
 +<code myjava> 
 +   double summe(double summand1, double summand2) 
 +</code> 
 +Beim Aufruf werden auch die Parameterwerte durch Kommas voneinander getrennt, z.B. 
 +<code myjava> 
 +   println(r.summe(2, 3.7)); 
 +</code> 
 +  * Die Parameter einer Methode können natürlich **verschiedene Datentypen** haben
 +  * Unterscheide im obigen Beispiel das **Komma** als Trennzeichen zwischen Parameterwerten vom **Dezimalpunkt**. 
 +  * **Gute Methodenbezeichner:** \\ Es ist guter Stil, Methoden, die keinen Wert zurückgeben, mit Verben zu bezeichnen, z.B. ''zeichneKreis'', ''würfle'' o.ä. \\ Methoden, die einen Wert zurückliefern, kann man auch mit Substantiven bezeichnen, die beschreiben, was zurückgeliefert wird, z.B. ''summe'' oder ''differenz''. \\ Per Konvention beginnen Methodenbezeichner immer mit einem Kleinbuchstaben. 
 +</WRAP> 
 + 
 +{{ :klassen1:eigene:pasted:20201028-133352.png?150}} 
 +===== Beispiel 3: Weihnachtsbaum (Methoden rufen sich gegenseitig auf) ===== 
 +Schreibe eine Klasse ''Baum'', mit einer Methode ''zeichneBaum(int breite)'', die wiederum die Methoden ''zeichneKrone(int breite)'' und ''zeichneStamm(int stammbreite)'' aufruft um damit einen Baum wie in der nebenstehenden Abbildung zu zeichnen
 + 
 +<HTML> 
 + 
 +<div class="java-online" style="height: 500px; width: 100%" data-java-online="{'withBottomPanel': false, 'id': 'Baum1'}"> 
 + 
 +<script type="text/plain" title="Main5.java"> 
 +Baum b = new Baum(); 
 +b.zeichneBaum(21); 
 + 
 +class Baum { 
 + 
 +   void zeichneBaum(int baumbreite) { 
 +      zeichneKrone(baumbreite); 
 +      zeichneStamm(baumbreite); 
 +   } 
 + 
 +   void zeichneKrone(int breite) { 
 +      for(int i = 1; i <= breite; i = i + 2) { 
 + 
 +         gibZeichenAus(" ", (breite - i) / 2, Color.white); 
 + 
 +         for(int j = 1; j <= i; j++) { 
 +            zeichneKronenPunkt(); 
 +         } 
 + 
 +         println(); 
 +      } 
 +   } 
 + 
 +   void zeichneKronenPunkt() { 
 +      if(Math.random() < 0.7) { 
 +         print("*"Color.green); 
 +      } else if(Math.random() < 0.4) { 
 +         print("i"Color.yellow); 
 +      } else { 
 +         print("o", Color.red); 
 +      } 
 +   } 
 + 
 +   void zeichneStamm(int baumbreite) { 
 +      int stammbreite = baumbreite / 5; 
 +      if(stammbreite % 2 == 0) { 
 +         stammbreite++; 
 +      } 
 +      if(stammbreite < 1) { 
 +         stammbreite = 1; 
 +      } 
 +       
 +      int stammhöhe = stammbreite * 3 / 2; 
 +      for(int zeile = 1; zeile <= stammhöhe; zeile++) { 
 +         gibZeichenAus(" ", (baumbreite - stammbreite) / 2, Color.white); 
 +         gibZeichenAus("T", stammbreite, Color.brown);  
 +         println();  
 +      } 
 +   } 
 + 
 +   void gibZeichenAus(String zeichen, int anzahl, String farbe) { 
 +      for(int i = 1; i <= anzahl; i++) { 
 +         print(zeichen, farbe); 
 +      } 
 +   } 
 + 
 +
 +</script> 
 +</div> 
 + 
 +</HTML> 
 + 
 +<WRAP center round info 60%> 
 +Methoden eines Objekts können **andere Methoden desselben Objekts aufrufen**Dadurch lassen sich komplexe Methoden (z.B. ''zeichneBaum'') in weniger komplexe Methoden (''zeichneKrone'', ''zeichneStamm'') zerlegen, die wiederum auf noch einfachere Methoden (''gibZeichenAus'') zurückgreifen, usw.  \\  
 +Aus einer Methode eines Objekts heraus ruft man eine andere Methode desselben Objekts auf, in dem man einfach ihren Bezeichner verwendet (ohne "Punktschreibweise"), z.B. 
 +<code myjava> 
 +   void zeichneBaum(int baumbreite) { 
 +      zeichneKrone(baumbreite); 
 +      zeichneStamm(baumbreite); 
 +   } 
 +</code>
 </WRAP> </WRAP>
 +
g9/uebungen/eigene_klassen/start.1611143666.txt.gz · Zuletzt geändert: 2021/12/29 11:29 (Externe Bearbeitung)

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki