Benutzer-Werkzeuge

Webseiten-Werkzeuge


g9:uebungen:attribute:start

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.


g9:uebungen:attribute:start [2024/08/31 12:03] (aktuell) – angelegt - Externe Bearbeitung 127.0.0.1
Zeile 1: Zeile 1:
 +====== Klassen/Objekte mit Attributen ======
 +<WRAP center round info 80%>
 +{{ :klassen2:attribute:pasted:20201108-211818.png?400}}
 +Ein **Attribut** eine Objektes ist eine **Eigenschaft**, die **einen Wert annehmen** kann. Im Bild rechts etwa ist ein Objekt der Klasse ''Rectangle'' zu sehen mit den Attributen ''width'' (Wert: 800), ''height'' (Wert: 400) und ''FillColor'' (Wert: ''blue''). Es kann viele weitere Objekte derselben Klasse geben. Sie haben **die selben Attribute** (''width'', ''height'', ...), aber diese können **andere Werte** haben. \\ \\ 
 +Siehe dazu auch das [[klassen1:grundbegriffe:start|Kapitel "Grundbegriffe der Objektorientierung"]].
 +</WRAP>
 +
 +===== Beispiel 1: Die Klasse Tier =====
 +Wir beginnen mit einem künstlichen - dafür aber sehr einfachen - Beispiel: Einer Klasse ''Tier'' mit den Attributen ''name'', ''art'' und ''anzahlBeine''
 +
 +<HTML>
 +
 +<div class="java-online" style="height: 450px; width: 100%" data-java-online="{'withBottomPanel': false, 'id': 'Attribute1'}">
 +
 +<script type="text/plain" title="Attribute1.java">
 +Tier s = new Tier();
 +s.name = "Snoopy";
 +s.art = "Katze";
 +s.anzahlBeine = 4;
 +
 +Tier g = new Tier();
 +g.name = "Gerda";
 +g.art = "Huhn";
 +g.anzahlBeine = 2;
 +
 +println(s.name);
 +println(g.anzahlBeine);
 +
 +class Tier {
 +   String name;
 +   String art;
 +   int anzahlBeine;
 +}
 +</script>
 +</div>
 +</HTML>
 +
 +<WRAP center round info 80%>
 +**Deklaration von Attributen:** \\ 
 +Attribute werden deklariert, indem man auf oberster Ebene innerhalb der Klassendeklaration (also **nicht** innerhalb einer Methode!) den Datentyp des Attributs gefolgt von seinem Bezeichner schreibt.
 +Es ist auch möglich, bei der Attributdeklaration einen Anfangswert anzugeben, z.B.
 +<code myJava>
 +   String art = "Katze";
 +</code>
 +
 +Auf die Attribute von Objekten kann man außerhalb der Klassendeklaration mithilfe der Punktschreibweise zugreifen. Wie das geht, siehst Du im obigen Beispiel.
 +</WRAP>
 +
 +===== Beispiel 2: Klassen mit Attributen und Methoden =====
 +
 +<WRAP center round info 80%>
 +Attributdeklarationen und Methodendeklarationen dürfen innerhalb einer Klassendeklaration beliebig hintereinander stehen. Es ist aber üblich, **gleich zu Beginn** einer Klassendeklaration **alle Attribute** der Klasse zu deklarieren und danach erst die Methoden. \\ \\ 
 +
 +Innerhalb von Methodendeklarationen kann man auf Attribute wie auf gewöhnliche Variablen durch Angabe ihres Bezeichners zugreifen. Du siehst das im obigen Beispiel in der Anweisung ''println(name)''. Ausgegeben wird der Wert des Attributs Name desjenigen Objekts, für das die Methode aufgerufen wurde.
 +
 +//Du fragst Dich vielleicht, wie der Compiler Attributdeklarationen und Methodendeklarationen unterscheiden kann?// \\ Den Unterschied macht die runde Klammer hinter dem Bezeichner einer Methode. Jetzt ist Dir sicher auch klar, weshalb bei Methoden ohne Parameter trotzdem die runden Klammern ''()'' benötigt werden.
 +
 +
 +</WRAP>
 +
 +
 +<HTML>
 +
 +<div class="java-online" style="height: 550px; width: 100%" data-java-online="{'withBottomPanel': false, 'id': 'Attribute2'}">
 +
 +<script type="text/plain" title="Attribute2.java">
 +Tier s = new Tier();
 +s.name = "Snoopy";
 +s.art = "Katze";
 +s.anzahlBeine = 4;
 +
 +Tier g = new Tier();
 +g.name = "Gerda";
 +g.art = "Huhn";
 +g.anzahlBeine = 2;
 +
 +s.stellDichVor();
 +g.stellDichVor();
 +
 +class Tier {
 +   String name;
 +   String art;
 +   int anzahlBeine;
 +
 +   void stellDichVor() {
 +      println("Ich heiße " + name + " und bin ein/e " + art);
 +   }
 +
 +}
 +</script>
 +</div>
 +</HTML>
 +
 +<WRAP center round tip 60%>
 +Führe das Programm schrittweise mit "step into ({{:klassen2:constructors:step-into-dark.png?nolink|}})" aus und beobachte, welchen Wert die Attribute ''name'' und ''art'' jeweils innerhalb der Methoden haben! Öffne dazu rechts den Variablen-Reiter. Die Objekte werden jeweils im "zugeklappten" Zustand gezeigt. Klappe sie auf! \\ \\ 
 +Wenn sich der Aktuelle Ausführungspunkt des Programms (grün hinterlegte Programmzeile) gerade innerhalb einer Methode befindet, wird das Objekt, für das die Methode aufgerufen wurde, immer mit ''this'' bezeichnet. Klappe daher auch das ''this''-Objekt im Reiter "Variablen" auf und schau' Dir seine Attributwerte an.
 +</WRAP>
 +
 +===== Aufgabe 1: RechteckHelfer =====
 +Schreibe eine Klasse ''RechteckHelfer'' mit den Methoden ''setzeLängeBreite(double länge, double breite)'', ''gibUmfang()'', ''gibFlächeninhalt()'' und ''gibDiagonalenlänge()''. Hier ein Hauptprogramm mit Ausgabe, das die Bedeutung der Methoden zeigt:
 +== Programm: ==
 +<code myJava>
 +RechteckHelfer rh = new RechteckHelfer();
 +rh.setzeLängeBreite(3, 4);
 +println(rh.gibUmfang());
 +println(rh.gibFlächeninhalt());
 +println(rh.gibDiagonalenlänge());
 +</code>
 +== Ausgabe ==
 +<code>
 +14
 +12
 +5
 +</code>
 +
 +**Tipp: ** Natürlich benötigt die Klasse auch zwei Attribute, um die Länge und Breite des Rechtecks zu speichern!
 +<HTML>
 +
 +<div class="java-online" style="height: 550px; width: 100%" data-java-online="{'withBottomPanel': false, 'id': 'AttributeAufgabe3'}">
 +
 +<script type="text/plain" title="AttributeAufgabe3.java">
 +RechteckHelfer rh = new RechteckHelfer();
 +rh.setzeLängeBreite(3, 4);
 +println(rh.gibUmfang());
 +println(rh.gibFlächeninhalt());
 +println(rh.gibDiagonalenlänge());
 +
 +// Jetzt bist Du dran: schreibe die Definition der Klasse RechteckHelfer!
 +
 +
 +</script>
 +</div>
 +</HTML>
 +
 +[[:klassen2:attribute:Aufgabe3Loesung:start|Hier geht's zur Lösung.]]
 +
 +
 +===== Aufgabe 2: Eine Klasse zum Bruchrechnen =====
 +Studiere die Klasse Bruch im Programm unten genau und ergänze folgende Methoden: 
 +  * ''subtrahiere(Bruch b2)''
 +  * ''multipliziere(Bruch b2)''
 +  * ''dividiere(Bruch b2)''
 +  * ''gibAusEcht()'' (gibt den Bruch ggf. als echten Bruch aus, also 3 1/2 statt 7/2)
 +  * ''erweitere(int faktor)''
 +
 +
 +<HTML>
 +
 +<div class="java-online" style="height: 550px; width: 100%" data-java-online="{'withBottomPanel': false, 'id': 'AttributeAufgabe4'}">
 +
 +<script type="text/plain" title="AttributeAufgabe4.java">
 +
 +Bruch b1 = new Bruch();
 +b1.setzeWert(7, 2);
 +
 +Bruch b2 = new Bruch();
 +b2.setzeWert(2, 3);
 +
 +b1.addiere(b2);
 +b1.gibAusUnecht();
 +
 +class Bruch {
 +   int zähler;
 +   int nenner;
 +
 +
 +   void setzeWert(int z, int n) {
 +      zähler = z;
 +      nenner = n;
 +   }
 +
 +   void gibAusUnecht() {
 +      println(zähler + "/" + nenner);
 +   }
 +
 +   void kürze() {
 +      
 +      // Ermittle den größten gemeinsamen Teiler von Zähler und Nenner
 +      int z1 = zähler;
 +      int z2 = nenner;
 +      while(z1 != z2) {
 +         int z3 = Math.abs(z2 - z1);
 +         if(z1 > z2) {
 +            z1 = z3;
 +         } else {
 +            z2 = z3;
 +         }
 +      }
 +
 +      // Der ggT von zähler und Nenner befindet sich jetzt in z1 und z2. 
 +      // Wir kürzen jetzt den Bruch, indem wir Zähler und Nenner durch deren 
 +      // größten gemeinsamen Teiler teilen:
 +      zähler = zähler / z1;
 +      nenner = nenner / z1;
 +
 +   }
 +
 +   void addiere(Bruch b) {
 +      zähler = zähler * b.nenner + b.zähler * nenner;
 +      nenner = nenner * b.nenner;
 +      kürze();
 +   }
 +
 +
 +}
 +
 +</script>
 +</div>
 +</HTML>
 +
 +[[:klassen2:attribute:Aufgabe4Loesung:start|Hier geht's zur Lösung.]]
 +
 +
 +<WRAP center round tip 60%>
 +**Für die Mathematik-Interessierten unter Euch: \\ Algorithmus zur Berechnung des größten gemeinsamen Teilers zweier Zahlen** \\ \\ 
 +In der Methode ''kürzen'' wird der größte gemeinsame Teiler von Zähler und Nenner berechnet. Die Strategie ist eine vereinfachte Variante des [[https://de.wikipedia.org/wiki/Euklidischer_Algorithmus|Euklidischen Algorithmus]] und basiert auf folgendem einfachen Satz: \\ \\ 
 +Wenn eine Zahl $x$ ein Teiler der Zahlen $a$ und $b$ ist, dann ist $x$ auch ein Teiler von $|a - b|$ und von $a + b$. \\ \\ 
 +**In Folgenden ein Beispiel zur Durchführung des Algorithmus, das - basierend auf dem eben genannten Satz - auch den Korrektheitsbeweis des Algorithmus skizziert:** \\ 
 +Wir bestimmen den ggT von $24$ und $80$ (und nennen ihn im Folgenden kurz $x$). 
 +  * $x$ ist Teiler beider Zahlen und teilt daher auch $80 - 24 = 56$. Wir nehmen jetzt die kleineren beiden dieser drei Zahlen (also $24$ und $56$) und setzen das Spiel damit fort.
 +  * $x$ ist Teiler von $24$ und $56$ und teilt daher auch $56 - 24 = 32$. Wir nehmen jetzt die kleineren beiden dieser drei Zahlen (also $32$ und $24$) und setzen das Spiel damit fort.
 +  * $x$ ist Teiler von $32$ und $24$ und teilt daher auch $32 - 24 = 8$. Wir nehmen jetzt die kleineren beiden dieser drei Zahlen (also $24$ und $8$) und setzen das Spiel damit fort.
 +  * $x$ ist Teiler von $24$ und $8$ und teilt daher auch $24 - 8 = 16$. Wir nehmen jetzt die kleineren beiden dieser drei Zahlen (also $16$ und $8$) und setzen das Spiel damit fort.
 +  * $x$ ist Teiler von $16$ und $8$ und teilt daher auch $16 - 8 = 8$. Wir nehmen jetzt die kleineren beiden dieser drei Zahlen (also $8$ und $8$) und sind fertig, denn wir wissen jetzt, dass der ggT von $24$ und $80$ ein Teiler von $8$ ist. Gleichzeitig ist aber $8$ auch ein Teiler von $24$ und $80$, teilt also auch deren ggT. Daher ist $8$ der gesuchte ggT.
 +
 +
 +  * **Halt, halt, nicht so schnell!!** \\ Warum ist $6$ auch ein Teiler von $24$ und $80$? \\ \\ Denk' Dir einfach alle Schritte wieder rückwärts: die $8$ teilt $8$ und $8$, also teilt sie auch die Summe $16 = 8 + 8$. Da sie also die $8$ und die $16$ teilt, teilt sie auch $8 + 16 = 24$. Da sie $8$ und $24$ teilt, teilt sie auch $8 + 24 = 32$,  usw. Am Ende all dieser Schritte steht fest: $8$ teilt auch $24$ und $80$.
 +</WRAP>