Java/Online-Bank: Unterschied zwischen den Versionen

Aus ZUM-Unterrichten
Markierung: 2017-Quelltext-Bearbeitung
Markierung: 2017-Quelltext-Bearbeitung
 
(41 dazwischenliegende Versionen von 2 Benutzern werden nicht angezeigt)
Zeile 1: Zeile 1:
Auf dieser Seite sollen Sie anhand der Simulation eines Online-Kontos selbst Klassen definieren und die grundlegenden Elemente einer (objektorientierten) Programmiersprache
* [[Java/Glossar#Klasse|Klasse]]
* [[Java/Glossar#Attribut|Attribut]]
* Datentypen für Zahlen: <code>double</code>, für Zeichenketten: <code>String</code>
* [[Quelltext]]
* Instanz eines Objektes
* den Objektinspektor von [[BlueJ]]
und deren Umsetzung in Java mit Hilfe von BlueJ kennen lernen.
{{Fortsetzung|
{{Fortsetzung|
vorher=Einstieg in die OOP|vorherlink=Java/Einstieg in die OOP|
vorher=Einstieg in die OOP|vorherlink=Java/Einstieg in die OOP|
weiter=Beispiel Uhr|weiterlink=Java/Uhr|
weiter=Algorithmik<br>(Logische Operatoren)|weiterlink=Java/Algorithmik|
übersicht=Einstieg in Java<br>(Übersicht)|übersichtlink=Java#Übersicht|}}
übersicht=Einstieg in Java<br>(Übersicht)|übersichtlink=Java#Übersicht|}}


== Einfache Theorie der Objektorientierten Programmierung ==
==Einfache Theorie der Objektorientierten Programmierung==
 
[[Datei:BlueJ Logo.gif|BlueJ Logo|right|200px]] Zunächst klären wir am Beispiel Vogel, was eine '''Klasse''' ist: Ähnlich wie in der Biologie gruppiert man  in  der  OOP  (Objektorientierten  Programmierung)  Objekte  und  fasst  sie  in  Klassen  zusammen.  Dabei  stellt sich die Frage,  was einen Vogel auszeichnet:  
[[Datei:BlueJ Logo.gif|BlueJ Logo|right|200px]] Zunächst klären wir am Beispiel Vogel, was eine '''Klasse''' ist: Ähnlich wie in der Biologie gruppiert man  in  der  OOP  (Objektorientierten  Programmierung)  Objekte  und  fasst  sie  in  Klassen  zusammen.  Dabei  stellt sich die Frage,  was einen Vogel auszeichnet:  


Ein  Vogel  hat  bestimmte  '''Eigenschaften''' (oder '''Attribute'''). Er hat zum Beispiel eine bestimmte Farbe,   ein   Geschlecht   und man kann seine Flügelspannweite messen.  
*Ein  Vogel  kann  bestimmte  Dinge  tun.  Er  kann etwa  singen  oder ein Ei legen.  Das  sind die sogenannten  '''Methoden (Operationen)'''  des Vogels (<code>singe(...), legeEi(...)</code> ). Methoden teilt man in zwei Gruppen ein:
**'''beobachtende''' oder '''sondierende''' Methoden z.B. <code>gibFarbe()</code> und
**'''verändernde''' oder '''manipulierende''' Methoden wie z.B. <code>setFarbe(“gruen“)</code>.
*Ein  Vogel  hat  auch bestimmte  '''Eigenschaften''' ('''Attribute'''). Er hat zum Beispiel eine bestimmte Farbe, ein Geschlecht, eine Flügelspannweite. Die Gesamtheit der Werte dieser Eigenschaften nennt man '''Zustand'''. Hierin unterscheiden sich verschiedene Objekte derselben Klasse.
*Aus der Klasse Vogel lassen sich dann konkrete Objekte bilden z.B. <code>vogel1</code>, <code>vogel2</code>, <code>vogel3</code>.
*Während die '''Klasse''' Vogel etwas '''abstraktes''' ist (eine Art Bauplan für Objekte), ist ein '''Objekt''' '''konkret'''.<br />


Ein  Vogel  kann  bestimmte  Dinge  tun.  Er  kann etwa  singen  oder ein Ei legen.  Das  sind die sogenannten  '''Methoden (Operationen)''' des Vogels (<code>singe(...), legeEi(...)</code> ).
{{Box|Zusammenfassung|
* '''Objekte''' sind in der objektorientierten Programmierung
** '''Daten''' (Eigenschaften oder auch Attribute) und
** die damit verknüpfte '''Programmlogik''' (Methoden oder auch Operationen),<br>die zu Einheiten, nämlich eben den Objekten, zusammengefasst sind.
* Gleichartige Objekte werden zu '''Klassen''' zusammengefasst.
* '''Klassen dienen als Vorlage''' (wie ein Bauplan) zur Herstellung von Objekten.  
* Von einer Klasse können beliebig viele Objekte hergestellt werden.
* Die '''Objekte sind einzigartig''', da sie einen unterschiedlichen Namen tragen müssen, obwohl ihr Zustand identisch sein kann.
* Der Zustand (oder auch Status) ist die Gesamtheit der Werte der Eigenschaften.|Hervorhebung}}


Methoden teilt man in zwei Gruppen ein:
==Beispiel: Online-Bank==
* Es  gibt  zum  einen  '''beobachtende'''  oder auch '''sondierende  Methoden'''.  Diese beantworten z.B. die Frage: Welche Farbe hast du?  Im  Programm  werden  sie <code>gibFarbe()</code> oder <code>getFarbe()</code> genannt.
===Die Klasse Konto===
* Zum  anderen  gibt  es  Methoden,  die Eigenschaften ändern können (verändernde  Methode).  Ein  Beispiel wäre <code>setFarbe(“gruen“)</code>.


Aus  der  Klasse  Vogel  lassen  sich  konkrete Objekte  bilden:  z.B.  vogel1,   vogel2,  vogel3. Jedes Objekt hat einen bestimmten  Zustand. Sokann z.B. vogel1 die Farbe gelb haben, weiblich sein und 40cm Spannweite haben. Der Zustand von vogel2 könnte sein: gelb, 30 cm Spannweite, männlich.  Während die Klasse Vogel etwas abstraktes ist (eine Art Bauplan für Objekte), ist ein Objekt konkret. Was das genau bedeutet, erfahren Sie, wenn  Sie  die  folgenden  Beispiele nachvollziehen.
Um ein Konto zu eröffnen, benötigt eine Bank zumindest


{{Box|Zusammenfassung|Objekte sind in der objektorientierten Programmierung Daten (Eigenschaften oder auch Atrribute)  und die  damit  verknüpfte  Programmlogik  (Methoden  oder  auch  Operationen), die zu Einheiten, nämlich eben den Objekten, zusammengefasst sind.
*den Namen des Besitzers <code>besitzerName</code> und
*den aktuellen Geldbetrag <code>kontostand</code>.


Gleichartige Objekte werden zu Klassen zusammengefasst.
Beides sind '''Attribute''' (bzw. Eigenschaften) der '''Klasse Konto'''.


Klassen dienen als Vorlage (wie ein Bauplan) zur Herstellung von Objekten. Von einer Klasse können beliebig viele Objekte hergestellt werden. Die Objekte sind einzigartig, dasie einen unterschiedlichen Namen tragen müssen, obwohl ihr Zustand identisch sein kann.
*Jedes Attribut verlangt die Angabe eines geeigneten '''Datentyps'''.
*Java kennt u.a. folgende '''Datentypen''':


Der Zustand (oder auch Status) ist die Gesamtheit der Werte der Eigenschaften.|Hervorhebung}}
{| class="wikitable" style="text-align:left"
!Typname
!Größe
!Wertebereich
!Beschreibung
|-----
|boolean||1 bit||true / false||Boolescher Wahrheitswert
|-
|int||32 bit||-2.147.483.648 ... 2.147.483.647||Zweierkomplement-Wert
|-
|float||32 bit||+/-1,4E-45 ... +/-3,4E+38||32-bit IEEE 754, einfache Genauigkeit
|-
|double||64 bit||+/-4,9E-324 ... +/-1,7E+308||64-bit IEEE 754, doppelte Genauigkeit
|-
|char||16 bit||0 ... 65.535 (z.B. 'A')||Unicode-Zeichen (UTF-16)
|-
|String|| || ||Zeichenkette (kein einfacher Datentyp,<br>sondern ein Objekt der Klasse String)
|}
====Eingabe des Quelltexts====
[[Datei:BlueJ Online-Bank 1.png|alternativtext=Online-Bank: Klasse Konto|mini|Online-Bank: Klasse Konto]]


=== Klassendiagramm und Objektdiagramm ===
*Mit "Projekt|neu" wird ein neues Projekt angelegt, das wir "Online-Bank" nennen.
[[Datei:Klassendiagramm-Vogel.png|300px|right]]
*Mit "Neue Klasse" legen wir eine Klasse mit dem Namen "Konto" an.
Im Klassendiagramm (auch UML-Klassendiagramm genannt) hält man die Elemente einer Klasse anschaulich fest: Klassenname, Eigenschaften und Methoden.  
*Wenn alles richtig geklappt hat, sollte es etwa so aussehen:
* Im '''Klassendiagramm''' werden Klassenname, Eigenschaften und Methoden festgehalten.
* Alle Methoden, die wir schreiben, sind '''öffentlich''', also <code>public</code>, alle '''Eigenschaften''' sind <code>private</code><br>Im Klassendiagramm bekommen Eigenschaften daher ein vorgestelltes <code> – </code> und Methoden ein <code>+</code>


{{Übung|#Skat
Mit einem Doppelklick auf das beige Rechteck kommt zum Editor, in dem man den Quelltext eintippen kann:[[Datei:BlueJ Online-Bank- Neue Instanz konto1-Konto.png|alternativtext=Neue Instanz konto1:Konto|mini|Neue Instanz konto1:Konto]]
## Was sind Eigenschaften der Klasse Kartenspiel?
<source lang="java">
## Was sind die Methoden?
public class Konto {
## Legen Sie ein Klassendiagramm an.
  // Instanzvariablen
# Nennen Sie Eigenschaften und Methoden des Objektes Kaffeemaschine.
  private String besitzerName;
## Legen Sie einKlassendiagramm an.}}
  private double kontostand;
}
</source>
und mit dem Button "Übersetzen" abspeichert und ''"compiliert"''.


== Beispiel: Online-Bank ==
*Die '''Definition''' der Klasse beginnt mit dem Schlüsselwort <code>public</code>
Wie sieht ein "Bauplan" zu einem Konto aus (z.B. Girokonto an einer Online-Bank)? Dazu beantworte ich die Frage, was ein Konto auszeichnet.
*Die '''Zugriffsmodifizierer''' <code>public</code> und <code>private</code> regeln die Zugriffsrechte.<br> Dies ist vergleichbar mit dem Zugriff auf ein technisches Gerät wie z.B. Handy, TV, Auto, Waschmaschine etc.:
=== Die Klasse Konto ===
**Die Bedienknöpfe sind <code>public</code>, also öffentlich und von jedem bedienbar.
Eine Online-Bank benötigt zumindest den Namen des Besitzers und den aktuell vorhandenen Geldbetrag, um ein Konto anzulegen.  
**Das Innenleben des Gerätes ist <code>private</code> und ein Laie sollte hier keinen Zugriff haben.


<code>besitzerName</code> und </code>kontostand</code> sind '''Attribute''' (auch Eigenschaften genannt) der '''Klasse Konto'''.  
[[Datei:BlueJ Online-Bank 3.png|alternativtext=Online-Bank: Objektinspektor|mini|500x500px]]
Als erste Faustregel genügt es, sich zu merken, dass


{{Definition|
*'''Attribute''' <code>private</code> (Innenleben der Klasse) und
Ein '''Attribut''' ist ein '''strukturelles Merkmal einer Klasse'''.
*'''Klassen''' <code>public</code>sind.
* Es hat einen '''Namen''' und einen '''Typ'''.  
* Konvention: Attributsnamen werden klein geschrieben.
}}


Die Namen von zwei Attributen des Kontos haben wir bereits festgelegt: ''besitzerName'' und ''kontostand''. Nun wird auch ein Typ ([[Java/Glossar#Datentyp|Datentyp]]) für jedes Attribut gefordert.
Instanzieren Sie nun ein Objekt <code>Konto1</code> der Klasse <code>Konto</code> mit der Methode <code>new Konto()</code> wähle.


Java kennt verschiedene Datentypen. Zwei für unseren Zweck geeignete sind <code>String</code> und <code>double</code>.
====Objektinspektor====
Ein Rechtsklick auf das rote Rechteck und dann auf Inspizieren öffnet den '''Objektinspektor'''. Dieser gibt einen Überblick über den '''Zustand''' des Objektes:


'''Zeichenketten''', also Aneinanderreihungen von Zeichen, werden in Java mit dem Datentypen '''String''' deklariert. Der Datentyp String eignet sich als Datentyp für <code>besitzerName</code>, da dieser aus beliebigen Zeichen der Tastatur besteht und nicht etwa eine Zahl ist.
*Unser Besitzer heißt <code>null</code>,<br> dem Anfangswert für String-Variablen.
 
*Der Kontostand ist <code>0</code>,<br> dem Anfangswert für numerische Variablen.
Als Typ des Kontostands </code>kontostand</code> bevorzugen wir einen numerischen Datentypen. <code>double</code> kann Zahlen im Bereich von +/-1,7E+308 (also 17 mit 307 Nullen) abspeichern, was für unseren Zweck genügen sollte.  


{{Box|Zusammenfassung|
*Eine  Klasse definiert man im Quelltextes. Der minimale Aufbau ist:
<source lang="java&quot;">
  public class Klassenname {
    // Instanzvariablen
    private Datentyp eigenschaft1;
    private Datentyp eigenschaft2;
  }
</source>
* Die Zugriffsmodifizierer <code>public</code> und <code>private</code> regeln die Zugriffsrechte.
* Als vorläufige Regel ist die Klasse immer <code>public</code> und die Eigenschaften immer <code>private</code>.
* Aus Klassen lassen sich Objekte erzeugen, die einen eindeutigen Namen tragen müssen.
* Die Objekte haben einen Zustand, den man mit Hilfe des Objektinspektors ansehen kann.
** Anfangszustand von Strings ist das englische Wort <code>null</code> und von Zahlentypen <code>0</code>.
* Ein „Doppelslash“ <code>//</code> am Anfang der Zeile macht aus der Zeile einen Kommentar, den der Computer ignoriert.|Hervorhebung2}}
{{Übung|
{{Übung|
* Nennen Sie mögliche Attribute einer Klasse Auto, Uhr und Kaffeemaschine. Wählen Sie entsprechend Datentypen für die Attribute.
# Erweitern Sie die Klasse Konto um die Attribute <code>kreditLimit</code> und <code>telefonNummer</code>.<br> Welche Datentypen würden Sie verwenden?
* Nennen Sie Fälle, bei denen der Zahlenbereich für double nicht ausreichend sein könnte.
# Recherchieren Sie, welche weiteren numerischen Datentypen Java bietet?
}}
}}


=== Der erste Quelltext der Klasse Konto ===
===Der Konstruktor===
Nach diesen Einführenden Überlegungen geht es nun daran, den Quelltext zu erarbeiten. Bei jedem Quelltext muss man sich an die Syntax der Programmiersprache richten. In Java beginnen wir damit, eine Klasse zu definieren. Dazu verwenden wir naheliegenderweise das Wort '''class'''.


==== Was bedeuten public und private? ====
Der  '''Konstruktor'''  ist eine  spezielle  Methode, die  bei der  Erzeugung von Variablen aufgerufen wird und diese in einen definierten Anfangszustand versetzt. Dieser Vorgang nennt sich auch '''Initialisierung'''.
[[Datei:LG 드럼세탁기와 식기세척기, 영국서 물사용 효율 최우수 제품 수상.jpg|right|200px|Eine moderne Waschmaschine]]
<source lang="java">
  public class Konto {
    // Instanzvariablen
    private String besitzerName;
    private double kontostand;
    // Konstruktor
    public Konto (String pBesitzerName){
      besitzerName = pBesitzerName; 
      kontostand = 1.0;
    }
  }
</source>


'''public''' und '''private'''' regeln die Zugriffsrechte (Fachbegriff: Zugriffsmodifizierer). Vergleichbar ist das mit dem Zugriff auf eine Waschmaschine:
{| class="wikitable"
* Die Bedienknöpfe sind <code>public</code>, also öffentlich und von jedem bedienbar.  
|-
* Das Innenleben ist <code>private</code>. Hier soll keine Hausfrau und erst Recht kein Hausmann Zugriff haben, da sie bzw. er etwas kaputtmachen könnte. Als erste Faustregel genügt es, sich zumerken, dass Attribute private (Innenleben der Klasse) und Klassen public sind (Jeder soll Klassen ausführen dürfen). Im Klassendiagramm zu Vogel haben  wir  bereits  Zugriffsmodifizierer  gesehen  (siehe  Konvention:Eigenschaften immer private, Klassen immer public)
!Begriff!!Erläuterung
{{clear}}
|-
==== Schritte zur Eingabe des Quelltexts ====
|'''Konstruktor'''||Ein Konstruktor ist eine spezielle Methode und legt die Anfangswerte fest. Er erhält den gleichen Namen wie die Klasse selbst z.B. public Konto. Alle Werte, die nicht im Konstruktor festgelegt werden, bekommen einen „default-Wert“. Bei Zahlentypen ist das 0,  bei Strings „null“
Nun kommt [[BlueJ]] ins Spiel. Mit "Projekt|neu" wird ein neues Projekt angelegt, das wir "Online-Bank" nennen wollen. Mit "Neue Klasse" legen wir eine Klasse mit dem Namen "Konto" an. Wenn alles richtig geklappt hat, sollte es etwa so aussehen:
|-
|(Übergabe-) '''Parameter'''||Sind die Werte, die der Methode beim Aufruf übergeben werden. Für jeden Parameter muss ein Datentyp festgelegt werden. Der Name des Parameters kann zur besseren Übersicht mit p beginnen.
|-
|geschweifte Klammern||Sie strukturieren das Programm: Die gesamte Klasse und jede Methoden wie z.B. der Konstruktor stehen in geschweiften Klammern. Das Weglassen von Klammern ist eine typische Fehlerquelle.
|-
|'''amerikanische Notation'''||Verwenden Sie im Quelltext


[[Bild:Onlinebank1.png|right]]
*bei Zahlendarstellungen stets '''Punkt statt Komma''': 3.141
*'''keine deutschen Umlaute oder Sonderzeichen'''!!
|-
|Semikolon||Nach (nahezu) jedem Befehl (Anweisung) möchte Java ein Semikolon ;
|}


Mit einem Doppelklick auf das beige Rechteck kommt zum Editor, in dem man den Quelltext eintippen kann und anschließend mit dem Button "Übersetzen" abspeichert und ''"compiliert"''.
{{Übung|
# Erweitern Sie die Instanzvariablen mit dem String <code>strassenName</code>.<br> Im Konstruktor trennen Sie mehrere Übergabeparameter durch Kommata: <code>public Konto (String pBesitzerName, String pStrassenName)</code>
# Testen Sie Fehleingaben bei BlueJ: Lassen Sie beim Besitzernamen die Anführungsstriche weg, geben Sie eine Zahl, geben Sie nichts ein &hellip;
# Lassen Sie statt des Namens den Kontostand als Parameter übergeben.
# Ergänzen Sie die Eigenschaften <code>vorname</code>, <code>telefonnummer</code>, <code>postleitzahl</code>, <code>geburtsjahr</code>, <code>geschlecht</code> und <code>hausnummer</code>. Begründen Sie dabei, welche Datentypen Sie verwenden.}}


 
===Methoden ===
[[Bild:Onlinebank2.png|right]]
Die Methode <code>einzahlen(double pBetrag)</code> sorgt dafür, dass zu dem bisherigen Kontostand ein bestimmter Betrag hinzugefügt wird:
<source lang="java">
<source lang="java">
public class Konto {
public void einzahlen(double pBetrag){
private String besitzerName;
  kontostand += pBetrag;  
private double kontostand;
  // oder kontostand = kontostand + pBetrag;
}
}</source>
</source>
Unten sollte nun zu sehen sein "Klasse übersetzt - keine Syntaxfehler". Wenn das nicht der Fall ist, beginnt die Suche nach Tippfehlern.


Nun sollten in dem Hauptfenster von BlueJ die Streifen von der Klassendarstellung verschwunden sein. Mit Hilfe der rechten Maustaste kann ich eine "''Instanz des Objektes Konto''" anlegen, indem ich <code>new Konto()</code> wähle.
====Zuweisen von Werten an Variablen====


Das "''Gleichheits''"-zeichen wird in Java nicht als Vergleichs-, sondern als '''Zuweisungsoperator''' verwendet:
* Auf der linken Seite des Zuweisungsoperators steht die Variable, die einen neuen Wert bekommen soll,
* auf der rechten Seite eine Rechnung, die den neuen Wert ergibt.<br> Die Variable links darf dabei als (alter) Variablenwert in der Rechnung rechts vorkommen:
** <code>x = y + 7</code> bedeutet, dass x den Wert der Rechnung y + 7 bekommt.
** <code>x = x + 7</code> bedeutet, dass x um 7 erhöht wird
** <code>x += 7</code> Kurzschreibweise: x wird um 7 erhöht (analog <code>-=</code>).
** <code>x *= 7</code> Kurzschreibweise: x wird mit 7 multipliziert (analog <code>/=</code>).
** <code>x++</code> x wird um 1 erhöht
** <code>x--</code> x wird um 1 erniedrigt


[[Bild:Onlinebank3.png]]
{{Übung|# Bauen Sie die Methode <code>einzahlen</code> in Ihre Kontoklasse ein.  
# Testen Sie das Einzahlen von negativen Beträgen, großen Beträgen, 0, Wörtern, Rechnungen...
# Entwerfen Sie auf Grundlage von <code>einzahlen</code> die Methode <code>auszahlen()</code>.
# Schreiben Sie die Methode <code>bucheZinsen (double pzinssatz)</code>,<br>die auf den vorliegenden Kontostand <code>zinssatz</code> Prozent Zinsen addiert.
# Entwerfen Sie <code>raubeAus()</code>, die den Kontostand auf 0 setzt.
}}


Ich wähle den vorgegebenen Instanznamen <code>Konto1</code> und schon habe ich mein Objekt, welches BlueJ unten links als rotes Rechteck visualisiert.
====Die set-Methoden als Beispiel für verändernde Methode ohne Rückgabewert====
Diese einfache Methode verändert den Namen des Kontobesitzers:
<source lang="java">
public void setBesitzerName(String pNeuerName){
  besitzerName = pNeuerName;
}</source>


[[Bild:Onlinebank4.png]]
{{Merke|Wann schreibt man void?
* <code>void</code> kommt bei einer Methodendeklaration immer dann vor, wenn es keine Rückgabe (void: nichts) gibt.
* <code>return</code> Gibt es eine Rückgabe (return variable), so muss der Datentyp des Rückgabewertes eingetragen werden.}}


==== Objektinspektor ====
====Die get-Methoden als Beispiel für sondierende Methoden====
Ein Rechtsklick auf das rote Rechteck und dann auf Inspizieren öffnet den '''Objektinspektor'''. Dieser gibt einen Überblick über den '''Zustand''' des Objektes: Unser Besitzer heißt '''null''', ein Wort, das Java verwendet, wenn String-Variablen noch keinen Wert haben. Der Kontostand ist 0, was der Anfangswert für alle numerischen Variablen ist.
Eine ebenso einfache Methode liest den Namen des Kontobesitzers wieder aus:
<source lang="java">
public String getBesitzerName(){
  return besitzerName;
}</source>


[[Bild:Onlinebank5.png]]
{{Übung|Schreiben Sie get-Methoden, die die den Kontostand und den Zinssatz ausgeben.}}


Zusammenfassung
==Interaktion zwischen Objekten==
* Eine  Klasse  (be-)schreibt man in BlueJ mit Hilfe eines  Quelltextes. Der grundsätzliche minimale Aufbau ist:
Zu einer Bank gehören mehrere Konten und neben Ein- und Auszahlungen auch Überweisungen bzw. '''Interaktionen''':
<source lang=java">public class Klassenname {
<source lang="java">
   // Eigenschaften
public void ueberweise(double pBetrag, Konto pZielkonto){
  private Datentyp eigenschaft1;  
   auszahlen(pBetrag);
   private Datentyp eigenschaft2;
   pZielkonto.einzahlen(pBetrag);
}</source>
}</source>
* Die Zugriffsmodifizierer public und private regeln die Zugriffsrechte. Als vorläufige Regel ist die Klasse immer public und die Eigenschaften sind immer private.
* Es gibt diesmal '''zwei Übergabeparameter''', die wir, wie schon beim Konstruktor, mit Komma trennen. Die Besonderheit ist, dass der Datentyp von Zielkonto wieder ein Konto ist.
* Aus Klassen lassen sich Objekte erzeugen, die einen eindeutigen Namen tragen müssen.
* Man darf sogar in Methoden den Datentypen der Klasse verwenden, zu dem die Methode gehört. Das ist sinnvoll, denn üblicherweise möchte man von einem Konto auf ein anderes Konto überweisen.
* Die Objekte haben einen Zustand, den man mit Hilfe des Objektinspektors ansehen kann. Anfangszustand von Strings ist das englische Wort <code>null</code> und von Zahlentypen <code>0</code>.
* Eigenschaften, die private sind, sind nur für Objekte der gleichen Klasse sichtbar. Theoretisch könnten wir von dem einen Konto auf die Eigenschaften des anderen Kontos direkt zugreifen. Damit es nicht zu Verwechslungen bzw. sogenannten Seiteneffekten kommt, sollten Sie das unbedingt vermeiden!!
* Ein „Doppelslash“ // am Anfang der Zeile macht aus der Zeile einen Kommentar, den der Computer ignoriert. Ein Kommentar erläutert den Quelltext.


Nun möchten wir natürlich andere Werte setzen, einzahlen, auszahlen usw.. Das wird das Konto auch noch können, allerdings bedarf es dazu eines weiteren Ausbaus.
{{Box|Konvention|
* Auf die Daten von '''fremden''' Objekten oder Klassen greifen wir  
**'''immer über Methoden''' und
**'''nie über deren Eigenschaften''' zu.
* Dies gewährleistet, dass nichts Ungewolltes verändert wird!. Deshalb sind sie ja ''private''!
* '''Nur innerhalb des Objektes selbst''' verändert man die eigenen Eigenschaften direkt.|Hervorhebung}}


Zunächst daher noch eine
{{Übung|# Schreiben Sie die Methode <code>holeEinzug (double pBetrag, Konto pZielkonto)</code>,<br> bei dem das Geld von einem fremden Konto überwiesen wird.
 
# Schreiben Sie die Methode <code>vererben (Konto erbe)</code>,<br> bei dem das gesamte Geld eines Kontos auf ein anderes verbucht wird.
{{Übung|
# Schreiben Sie die Methode <code>binIchReich(Konto vergleichskonto)</code>,<br> das die Differenz aus dem eigenen Kontostand mit einem anderen Konto vergleicht.
# Erweitern Sie die Klasse Konto um die Attribute <code>kreditlimit</code> und <code>telefonnummer</code>. Welche Datentypen würden Sie verwenden?
# Schreiben Sie die Methode <code>stifteVerwirrung(Konto konto1, Konto konto2)</code>,<br> bei der ein unbeteiligtes Konto dafür sorgt, dass das gesamte Geld von <code>konto1</code> auf </code>konto2</code> überwiesen wird.
# Entwerfen Sie das Klassendiagramm zur Klasse Konto. Entwerfen Sie den Quelltext zur Klasse Vogel.
# Schreiben Sie die Methode <code>stifteNochMehrVerwirrung(Konto konto1, Konto konto2)</code>,<br> bei der ein unbeteiligtes Konto dafür sorgt, dass das gesamte Geld von <code>konto1</code> halbiert, das von <code>konto2</code> aber verdoppelt wird.  
# Profis: Recherchieren Sie zum Thema "Genauigkeit von Fließkommazahlen", nach den Grenzen der Genauigkeit des Typs double. Welche weiteren numerischen Datentypen bietet Java?  
# Lassen Sie von einem Konto den Namen des Besitzers eines anderen Kontos ändern. Welche Probleme ergeben sich, wenn Sie die Methode <code>setBesitzerName</code> weglassen?
}}
}}


=== Konstruktor – Wie sind die Ausgangswerte? ===
{{Fortsetzung|
Der  '''Konstruktor'''  ist eine  spezielle  Methode, die  bei der  Erzeugung von Variablen aufgerufen wird. Er wird dazu verwendet, die Variable in einen definierten Anfangszustand zu versetzen.Dieser Vorgang nennt sich auch Initialisierung.
vorher=Einstieg in die OOP|vorherlink=Java/Einstieg in die OOP|
 
weiter=Algorithmik<br>(Logische Operatoren)|weiterlink=Java/Algorithmik|
Wir erweitern die Klasse Konto wie folgt:
übersicht=Einstieg in Java<br>(Übersicht)|übersichtlink=Java#Übersicht|}}
<source lang="java">public class Konto {
  // (Instanzvariablen der) Eigenschaften
  private String besitzerName;
  private double kontostand;
  //Konstruktor
  public Konto (String pBesitzerName){
    besitzerName = pBesitzerName; 
    kontostand = 1.0;
  }
}</source>
 
{|class="wikitable"
|-
! Begriff !! Erläuterung
|-
| Konstruktor || legt die Anfangswerte fest. Er erhält den gleichen Namen wie die Klasse selbst: z.B. public Konto<br> Ein Konstruktor ist eine spezielle Methode. Alle Werte, die nicht im Konstruktor festgelegt werden, bekommen einen „default-Wert“. Bei Zahlentypen ist das 0,  bei Strings „null“
|-
|(Übergabe-)parameter || Sind die Werte, die der Methode übergeben werden. Für jeden Parameter muss ein Datentyp festgelegt werden. Der Name des Parameters kann zur besseren Übersicht mit p beginnen: z.B. <code>pBesitzerName</code>
|-
|null || Ist ein leeres Objekt. Es zeigt an, wenn eine Variable bzw. ein Objekt nicht mit einem Wert belegt wurde.
|-
|geschweifte Klammern <code>{ }</code> || Tippt man mit Strg + Alt + 7 bzw. 0. Sie werden eingesetzt, um das Programm zu strukturieren.Die gesamte Klasse steht in geschweiften Klammern und auch Methoden wie der Konstruktor. Das Weglassen von Klammern ist eine typische Fehlerquelle.Das letzte Zeichen einer Klasse ist „}“ (vgl. oben)
|-
| amerikanische Notation|| Java ist amerikanisch, daher Punkt statt Komma: 3.141
|-
|Semikolon || Nach (nahezu) jedem Befehl (Anweisung) möchte Java ein Semikolon ;
|}


=== Mehrere Parameter ===
==Weitere Beispiele==  
Möchte ich mehrere Parameter übergeben, so trenne ich sie mit einem Komma. Als Beispiel füge ich den Straßennamen hinzu (Hinweis: Im Quelltext meide ich deutsche Umlaute als Variablennamen).
===Der Zähler===
* Der Zähler ist eine einfache Klasse, bei dem Sie bei Aufruf der Methode <code>erhoeheZaehlerstand()</code> den Zähler um 1 erhöhen.
* Anwendungen: Verkehrszählungen, Heizungsverbrauchzähler, Bildzähler bei einer  Kamera,  Rundenzähler  bei  der  Carrera-Bahn...
* Bei  den  realen  Anwendungen  kommt  der Impuls von einem Sensor bzw. einen Druckknopf. Bei der Simulation müssen Sie statt dessen eine Methode ausführen.  


<source lang="java">
<source lang="java">  
public class Konto {
public class Zaehler{
  // Eigenschaften
    // Instanzvariablen der Eigenschaften
  private String besitzerName;
    int zaehlerstand;
  private String strassenName;
    // Konstruktor
  private double kontostand;
    public Zaehler(){ 
  //Konstruktor
        // Der Anfangszählerstand soll immer 0 sein.
  public Konto (String pBesitzerName, String pStrassenName){
        zaehlerstand=0;
    besitzerName = pBesitzerName;
    }
    strassenName = pStrassenName;
    // Methoden
    kontostand = 1.0;  
    public void erhoeheZaehlerstand(){
  }
        zaehlerstand += 1;
        // oder zaehlerstand++;
        // oder zaehlerstand=zaehlerstand+1;
    }
}</source>
}</source>


{{Übung:|# Vollziehen Sie das angegebene Beispiel nach. Testen Sie Fehleingaben bei BlueJ: Lassen Sie beim Besitzernamen die Anführungstsriche weg, geben Sie eine Zahl, geben Sie nichts ein &hellip;
===Das Telefonbuch===
# Lassen Sie statt des Namens den Kontostand als Parameter übergeben.
[[Datei:Klassendiagramm-Telefonbuch.png|300px|right]]
# Ergänzen Sie die Eigenschaften <code>vorname</code>, <code>telefonnummer</code>, <code>postleitzahl</code>, <code>geburtsjahr</code>, <code>geschlecht</code> und <code>hausnummer</code>. Begründen Sie dabei, welche Datentypen Sie verwenden.
* Die Telefonnummer wird, obwohl sie laut Name eine Nummer ist, als String eingelesen, um Eingaben wie „/“ zwischen Vorwahl und Nummer zuzulassen.  
=== Methoden – Was kann meine Klasse? ====
* Die Besonderheit an dieser Klasse ist, dass <code>name</code> nur durch den Konstruktor verändert werden kann. D.h. ich kann zwar mit  <code>setTelefonnummer</code> nachträglich  Telefonnummern  ändern, aber der Name bleibt erhalten.
Die Methode <code>einzahlen()</code> als Beispiel für eine verändernde Methode
* Allenfalls durch das Löschen des Objektes kann ich Personen aus dem Telefonbuch entfernen.
<source lang="java">public class Telefonbuch {
    // Eigenschaften


Es sind natürlich noch viele weitere Methoden möglich. Ein weiteres Beispiel ist die Methode ein-zahlen().
    // Anfang Variablen
    public String name;
    public String telefonnummer;
    // Ende Variablen


<source lang="java">
    // Konstruktor
public void einzahlen(doublepBtrag){
    public Telefonbuch(String name, String telefonnummer) {
  kontostand += pBetrag;     
        // ... Hier fehlen 2 Zeilen. Bitte nachtragen! (vgl. Übung)
  // oder kontostand = kontostand + pBetrag;
    }
}<</source>
Diese Methode sorgt dafür, dass zu dem bisherigen Kontostand ein bestimmter Betrag hinzugefügt wird. Hervorzuheben ist, dass die folgende Zeile nicht mathematisch zu verstehen ist:


kontostand = kontostand + pBetrag;
    // Anfang Ereignisprozeduren
    // Methoden
    public String getTelefonnummer() {
        return telefonnummer;
    }


Das bedeutet: kontostand wird die Summe aus dem  bisherigen  Kontostand und einem Parameter <code>pBetrag</code> '''zugewiesen'''.
    public void setTelefonnummer(String pTelefonnummer) {
        telefonnummer = pTelefonnummer;
    }


{{Übung|# Bauen Sie die Methode <code>einzahlen</code> in Ihre Kontoklasse ein. Testen Sie das Einzahlen von negativen Beträgen, großen Beträgen, 0, Wörtern, Rechnungen...
    public String getName() {
# Entwerfen Sie auf Grundlage von <code>einzahlen</code> die Methode <code>auszahlen()</code>.
        return name;
# Entwerfen Sie <code>raubeAus()</code>, die den Kontostand auf 0 setzt.}}
    }
    // Ende Ereignisprozeduren
}}</source>


{{Box|Zuweisen von Werten bei Variablen|
===Das Auto===
* Das '''Gleichheitszeichen''' wird in Java als '''Zuweisungsoperator''' verwendet.
[[Datei:Klassendiagramm-Auto.png|right|300px]]
* Zum Erhöhen einer Variable lässt sich += verwenden (analog -=, *=, /=).
Die Klasse simuliert ein Auto, erfasst aber nur Daten um den Tank und den Verbrauch.
* Zum Erhöhen um 1 kann man ++ schreiben (analog --).<br>x = y + 7 bedeutet, dass x den Wert der Rechnung y + 7 bekommt.<br>x = x + 1 bedeutet, dass x um 1 erhöht wird (auch andere Zahlen möglich)<br>x += 1 gleichbedeutend: x wird um 1 erhöht (auch andere Zahlen möglich)<br>x++ gleichbedeutend:  x wird um 1 erhöht (geht nur bei 1)<br>x = 2 * x bedeutet, dass x verdoppelt wird.
* Die manipulierenden Methoden <code>tanke(..)</codeund <code>fahre(...)</code> beeinflussen den aktuellen Füllstand.
* Auf  der linken Seite des Gleichheitszeichens steht ausschließlich die Variable, die einen neuen Wert bekommen soll. Auf der rechten Seite steht eine Rechnung, die den neuen Wert ergibt. Dabei darf die Variable links als Wert in der Rechnung rechts vorkommen. Dort wird der alte Variablenwert benutzt.
* Die sondierende Methode <code>getAktuelleMaximaleReichweite</code> gibt die Reichweite in km zurück, der beim aktuellen Füllstand noch gefahren werden kann.  
* Das Gleichheitszeichen hat eine andere Bedeutung als in der Mathematik!|Hervorhebung}}
* Die Probleme der Klasse liegen noch darin, dass man (über das Tankvolumen hinaus) soviel tanken kann wie man will und dass der Tankinhalt auch in den negativen Bereich fahren kann (Dispokredit bei der Tankstelle). Das können wir erst lösen, wenn wir die bedingte Ausführung kennen gelernt haben.
<source lang="java">public class Auto {
    private double volumenTank;
    private double verbrauchAuf100km;
    private double aktuellerFuellstand;


==== Die set-Methoden als Bspl. für verändernde Methode ohne Rückgabewert ====
    // Konstruktor
Diese einfache Methode verändert den Namen des Kontobesitzers. Eine Methode ohne Rückgabewert wird mit <code>public void</code> (void entspricht im englischen etwa: nichts) eingeleitet.
    public Auto(double pVolumenTank, double pVerbrauchAuf100km) {
        volumenTank = pVolumenTank;
        verbrauchAuf100km = pVerbrauchAuf100km;
        aktuellerFuellstand = 0; // Bei Auslieferung ist der Tank leer
    }


<source lang="java">
    // Methoden
public void setBesitzerName(String pNeuerName){
    public void setAktuellerFuellstand(double pAktuellerFuellstand) {
  besitzerName = pNeuerName;  
        aktuellerFuellstand = pAktuellerFuellstand;
}</source>
    }
1.6.2Die get-Methoden als Beispiel für sondierende Methoden Eine ebenso einfache Methode liest den Namen des Kontobesitzers wieder aus:
    public double getAktuellerFuellstand() {
 
        return aktuellerFuellstand;
<source lang="java">
    }
public String getBesitzerName(){
    public double getVerbrauchAuf100km() {
  return besitzerName;
        return verbrauchAuf100km;
    }
    public double getVolumenTank() {
        return volumenTank;
    }
    public void tanke(double menge) {
        this.aktuellerFuellstand+=menge; // füge Menge hinzu
    }
    public void fahre(double pKilometerZahl) {
        // Die Formel sagt folgendes aus:
        // vom aktuellen Füllstand wird abgezogen: der Verbruch bei der Kilometerzahl 
        aktuellerFuellstand -= pKilometerZahl / 100 * verbrauchAuf100km;  
    } 
}</source>
}</source>


{{Merke|Wann schreibe ich void?|
* <code>void</code> kommt bei einer Methodendeklaration immer dann vor, wenn es keine Rückgabe gibt.
* <code>return</code> Gibt es eine Rückgabe (return variable), so muss der Datentyp des Rückgabewertes eingetragen werden.}}


{{Übung:|# Schreiben Sie die get- und set-Methode zu der Eigenschaft kontostand.
{{Übung|# Analysieren und testen Sie alle 3 Programme. Warum bekommt nicht jede Eigenschaft eine get- und eine set-Methode?
# Schreiben Sie die Methode bucheZinsen (double zinssatz), die auf den vorliegendenKontostand zinssatz Prozent Zinsen addiert.
# Zu Zähler:
# Zeichnen Sie das Klassendiagramm zu der aktuellen Klasse Konto.
## Ergänzen Sie die Methode: <code>getZaehlerstand()</code>
## Ergänzen Sie die Methode: <code>aufNullSetzen()</code> und <code>erhöheUm(double pZahl)</code>
# Zu Telefonbuch: Ergänzen Sie die fehlenden Zeilen zum Konstruktor.
## Ergänzen Sie die Eigenschaften <code>geburtsdatum</code> (ggf. noch <code>schuhgrösse</code>).
## Welchen Datentypen verwenden Sie?
## Benötigt die Eigenschaft eine set-Methode?
# Zum Auto: Ergänzen Sie die Methode: <code>getMaximaleReichweiteBeiVollemTank()</code>
# Entwickeln Sie die Klasse Handy, die die Eigenschaften <code>telefonnummer</code>, <code>guthaben</code> und <code>gespraechskostenProMinute</code>. Entwickeln Sie geeignete Methoden.  
# Übung für Fortgeschrittene: Realisieren Sie die Klasse Bruch mit den Eigenschaften <code>zaehler</code> und <code>nenner</code> und realisieren Sie die Methoden <code>addierenEinerGanzenZahl</code>, <code>kuerzen</code> und <code>erweitern</code>. Wenn Sie schon Vorwissen haben, können Sie hier für eine erweiterte Variante schauen: [https://drdanielappel.de/informatik/mein-kleines-java-tutorium/2-einstieg-in-die-objektorietierte-programmierung/2-04-anwendungsbeispiel-bruchrechnung/ Anwendungsbeispiel Bruchrechnung] (drdanielappel.de)}}


{{Fortsetzung|
{{Fortsetzung|
vorher=Einstieg in die OOP|vorherlink=Java/Einstieg in die OOP|
vorher=Einstieg in die OOP|vorherlink=Java/Einstieg in die OOP|
weiter=Beispiel Uhr|weiterlink=Java/Uhr|
weiter=Algorithmik<br>(Logische Operatoren)|weiterlink=Java/Algorithmik|
übersicht=Einstieg in Java<br>(Übersicht)|übersichtlink=Java#Übersicht|}}
übersicht=Einstieg in Java<br>(Übersicht)|übersichtlink=Java#Übersicht|}}


== Weblinks ==
==Weblinks==
* vgl. {{wpde|Objektorientierte Programmierung#Klassen|Klassen}}
 
* vgl. {{wpde|Attribut (UML2)|Attribut (UML2)}}
*vgl. {{wpde|Objektorientierte Programmierung#Klassen|Klassen}}
* http://www.informatik.ursulaschule.de/index.php?cid=368
*vgl. {{wpde|Attribut (UML2)|Attribut (UML2)}}
*http://www.informatik.ursulaschule.de/index.php?cid=368


[[Kategorie:Java]]
[[Kategorie:Java]]
[[Kategorie:Informatik]]
[[Kategorie:Informatik]]
[[Kategorie:Unterrichtsidee]]
[[Kategorie:Unterrichtsidee]]

Aktuelle Version vom 27. November 2019, 18:48 Uhr

Einfache Theorie der Objektorientierten Programmierung

BlueJ Logo

Zunächst klären wir am Beispiel Vogel, was eine Klasse ist: Ähnlich wie in der Biologie gruppiert man in der OOP (Objektorientierten Programmierung) Objekte und fasst sie in Klassen zusammen. Dabei stellt sich die Frage, was einen Vogel auszeichnet:

  • Ein Vogel kann bestimmte Dinge tun. Er kann etwa singen oder ein Ei legen. Das sind die sogenannten Methoden (Operationen) des Vogels (singe(...), legeEi(...) ). Methoden teilt man in zwei Gruppen ein:
    • beobachtende oder sondierende Methoden z.B. gibFarbe() und
    • verändernde oder manipulierende Methoden wie z.B. setFarbe(“gruen“).
  • Ein Vogel hat auch bestimmte Eigenschaften (Attribute). Er hat zum Beispiel eine bestimmte Farbe, ein Geschlecht, eine Flügelspannweite. Die Gesamtheit der Werte dieser Eigenschaften nennt man Zustand. Hierin unterscheiden sich verschiedene Objekte derselben Klasse.
  • Aus der Klasse Vogel lassen sich dann konkrete Objekte bilden z.B. vogel1, vogel2, vogel3.
  • Während die Klasse Vogel etwas abstraktes ist (eine Art Bauplan für Objekte), ist ein Objekt konkret.

Zusammenfassung
  • Objekte sind in der objektorientierten Programmierung
    • Daten (Eigenschaften oder auch Attribute) und
    • die damit verknüpfte Programmlogik (Methoden oder auch Operationen),
      die zu Einheiten, nämlich eben den Objekten, zusammengefasst sind.
  • Gleichartige Objekte werden zu Klassen zusammengefasst.
  • Klassen dienen als Vorlage (wie ein Bauplan) zur Herstellung von Objekten.
  • Von einer Klasse können beliebig viele Objekte hergestellt werden.
  • Die Objekte sind einzigartig, da sie einen unterschiedlichen Namen tragen müssen, obwohl ihr Zustand identisch sein kann.
  • Der Zustand (oder auch Status) ist die Gesamtheit der Werte der Eigenschaften.

Beispiel: Online-Bank

Die Klasse Konto

Um ein Konto zu eröffnen, benötigt eine Bank zumindest

  • den Namen des Besitzers besitzerName und
  • den aktuellen Geldbetrag kontostand.

Beides sind Attribute (bzw. Eigenschaften) der Klasse Konto.

  • Jedes Attribut verlangt die Angabe eines geeigneten Datentyps.
  • Java kennt u.a. folgende Datentypen:
Typname Größe Wertebereich Beschreibung
boolean 1 bit true / false Boolescher Wahrheitswert
int 32 bit -2.147.483.648 ... 2.147.483.647 Zweierkomplement-Wert
float 32 bit +/-1,4E-45 ... +/-3,4E+38 32-bit IEEE 754, einfache Genauigkeit
double 64 bit +/-4,9E-324 ... +/-1,7E+308 64-bit IEEE 754, doppelte Genauigkeit
char 16 bit 0 ... 65.535 (z.B. 'A') Unicode-Zeichen (UTF-16)
String Zeichenkette (kein einfacher Datentyp,
sondern ein Objekt der Klasse String)

Eingabe des Quelltexts

Online-Bank: Klasse Konto
Online-Bank: Klasse Konto
  • Mit "Projekt|neu" wird ein neues Projekt angelegt, das wir "Online-Bank" nennen.
  • Mit "Neue Klasse" legen wir eine Klasse mit dem Namen "Konto" an.
  • Wenn alles richtig geklappt hat, sollte es etwa so aussehen:

Mit einem Doppelklick auf das beige Rechteck kommt zum Editor, in dem man den Quelltext eintippen kann:

Neue Instanz konto1:Konto
Neue Instanz konto1:Konto
public class Konto {
  // Instanzvariablen
  private String besitzerName;
  private double kontostand;
}

und mit dem Button "Übersetzen" abspeichert und "compiliert".

  • Die Definition der Klasse beginnt mit dem Schlüsselwort public
  • Die Zugriffsmodifizierer public und private regeln die Zugriffsrechte.
    Dies ist vergleichbar mit dem Zugriff auf ein technisches Gerät wie z.B. Handy, TV, Auto, Waschmaschine etc.:
    • Die Bedienknöpfe sind public, also öffentlich und von jedem bedienbar.
    • Das Innenleben des Gerätes ist private und ein Laie sollte hier keinen Zugriff haben.
Online-Bank: Objektinspektor

Als erste Faustregel genügt es, sich zu merken, dass

  • Attribute private (Innenleben der Klasse) und
  • Klassen publicsind.

Instanzieren Sie nun ein Objekt Konto1 der Klasse Konto mit der Methode new Konto() wähle.

Objektinspektor

Ein Rechtsklick auf das rote Rechteck und dann auf Inspizieren öffnet den Objektinspektor. Dieser gibt einen Überblick über den Zustand des Objektes:

  • Unser Besitzer heißt null,
    dem Anfangswert für String-Variablen.
  • Der Kontostand ist 0,
    dem Anfangswert für numerische Variablen.

Zusammenfassung
  • Eine Klasse definiert man im Quelltextes. Der minimale Aufbau ist:
  public class Klassenname {
    // Instanzvariablen
    private Datentyp eigenschaft1; 
    private Datentyp eigenschaft2;
  }
  • Die Zugriffsmodifizierer public und private regeln die Zugriffsrechte.
  • Als vorläufige Regel ist die Klasse immer public und die Eigenschaften immer private.
  • Aus Klassen lassen sich Objekte erzeugen, die einen eindeutigen Namen tragen müssen.
  • Die Objekte haben einen Zustand, den man mit Hilfe des Objektinspektors ansehen kann.
    • Anfangszustand von Strings ist das englische Wort null und von Zahlentypen 0.
  • Ein „Doppelslash“ // am Anfang der Zeile macht aus der Zeile einen Kommentar, den der Computer ignoriert.

Übung
  1. Erweitern Sie die Klasse Konto um die Attribute kreditLimit und telefonNummer.
    Welche Datentypen würden Sie verwenden?
  2. Recherchieren Sie, welche weiteren numerischen Datentypen Java bietet?


Der Konstruktor

Der Konstruktor ist eine spezielle Methode, die bei der Erzeugung von Variablen aufgerufen wird und diese in einen definierten Anfangszustand versetzt. Dieser Vorgang nennt sich auch Initialisierung.

  public class Konto {
    // Instanzvariablen
    private String besitzerName;
    private double kontostand;
    // Konstruktor
    public Konto (String pBesitzerName){
      besitzerName = pBesitzerName;  
      kontostand = 1.0; 
    }
  }
Begriff Erläuterung
Konstruktor Ein Konstruktor ist eine spezielle Methode und legt die Anfangswerte fest. Er erhält den gleichen Namen wie die Klasse selbst z.B. public Konto. Alle Werte, die nicht im Konstruktor festgelegt werden, bekommen einen „default-Wert“. Bei Zahlentypen ist das 0, bei Strings „null“
(Übergabe-) Parameter Sind die Werte, die der Methode beim Aufruf übergeben werden. Für jeden Parameter muss ein Datentyp festgelegt werden. Der Name des Parameters kann zur besseren Übersicht mit p beginnen.
geschweifte Klammern Sie strukturieren das Programm: Die gesamte Klasse und jede Methoden wie z.B. der Konstruktor stehen in geschweiften Klammern. Das Weglassen von Klammern ist eine typische Fehlerquelle.
amerikanische Notation Verwenden Sie im Quelltext
  • bei Zahlendarstellungen stets Punkt statt Komma: 3.141
  • keine deutschen Umlaute oder Sonderzeichen!!
Semikolon Nach (nahezu) jedem Befehl (Anweisung) möchte Java ein Semikolon ;

Übung
  1. Erweitern Sie die Instanzvariablen mit dem String strassenName.
    Im Konstruktor trennen Sie mehrere Übergabeparameter durch Kommata: public Konto (String pBesitzerName, String pStrassenName)
  2. Testen Sie Fehleingaben bei BlueJ: Lassen Sie beim Besitzernamen die Anführungsstriche weg, geben Sie eine Zahl, geben Sie nichts ein …
  3. Lassen Sie statt des Namens den Kontostand als Parameter übergeben.
  4. Ergänzen Sie die Eigenschaften vorname, telefonnummer, postleitzahl, geburtsjahr, geschlecht und hausnummer. Begründen Sie dabei, welche Datentypen Sie verwenden.


Methoden

Die Methode einzahlen(double pBetrag) sorgt dafür, dass zu dem bisherigen Kontostand ein bestimmter Betrag hinzugefügt wird:

public void einzahlen(double pBetrag){
  kontostand += pBetrag;   
  // oder kontostand = kontostand + pBetrag;
}

Zuweisen von Werten an Variablen

Das "Gleichheits"-zeichen wird in Java nicht als Vergleichs-, sondern als Zuweisungsoperator verwendet:

  • Auf der linken Seite des Zuweisungsoperators steht die Variable, die einen neuen Wert bekommen soll,
  • auf der rechten Seite eine Rechnung, die den neuen Wert ergibt.
    Die Variable links darf dabei als (alter) Variablenwert in der Rechnung rechts vorkommen:
    • x = y + 7 bedeutet, dass x den Wert der Rechnung y + 7 bekommt.
    • x = x + 7 bedeutet, dass x um 7 erhöht wird
    • x += 7 Kurzschreibweise: x wird um 7 erhöht (analog -=).
    • x *= 7 Kurzschreibweise: x wird mit 7 multipliziert (analog /=).
    • x++ x wird um 1 erhöht
    • x-- x wird um 1 erniedrigt

Übung
  1. Bauen Sie die Methode einzahlen in Ihre Kontoklasse ein.
  2. Testen Sie das Einzahlen von negativen Beträgen, großen Beträgen, 0, Wörtern, Rechnungen...
  3. Entwerfen Sie auf Grundlage von einzahlen die Methode auszahlen().
  4. Schreiben Sie die Methode bucheZinsen (double pzinssatz),
    die auf den vorliegenden Kontostand zinssatz Prozent Zinsen addiert.
  5. Entwerfen Sie raubeAus(), die den Kontostand auf 0 setzt.


Die set-Methoden als Beispiel für verändernde Methode ohne Rückgabewert

Diese einfache Methode verändert den Namen des Kontobesitzers:

public void setBesitzerName(String pNeuerName){
  besitzerName = pNeuerName; 
}

Merke

Wann schreibt man void?

  • void kommt bei einer Methodendeklaration immer dann vor, wenn es keine Rückgabe (void: nichts) gibt.
  • return Gibt es eine Rückgabe (return variable), so muss der Datentyp des Rückgabewertes eingetragen werden.


Die get-Methoden als Beispiel für sondierende Methoden

Eine ebenso einfache Methode liest den Namen des Kontobesitzers wieder aus:

public String getBesitzerName(){
  return besitzerName;
}

Übung
Schreiben Sie get-Methoden, die die den Kontostand und den Zinssatz ausgeben.


Interaktion zwischen Objekten

Zu einer Bank gehören mehrere Konten und neben Ein- und Auszahlungen auch Überweisungen bzw. Interaktionen:

public void ueberweise(double pBetrag, Konto pZielkonto){
  auszahlen(pBetrag);  
  pZielkonto.einzahlen(pBetrag);
}
  • Es gibt diesmal zwei Übergabeparameter, die wir, wie schon beim Konstruktor, mit Komma trennen. Die Besonderheit ist, dass der Datentyp von Zielkonto wieder ein Konto ist.
  • Man darf sogar in Methoden den Datentypen der Klasse verwenden, zu dem die Methode gehört. Das ist sinnvoll, denn üblicherweise möchte man von einem Konto auf ein anderes Konto überweisen.
  • Eigenschaften, die private sind, sind nur für Objekte der gleichen Klasse sichtbar. Theoretisch könnten wir von dem einen Konto auf die Eigenschaften des anderen Kontos direkt zugreifen. Damit es nicht zu Verwechslungen bzw. sogenannten Seiteneffekten kommt, sollten Sie das unbedingt vermeiden!!

Konvention
  • Auf die Daten von fremden Objekten oder Klassen greifen wir
    • immer über Methoden und
    • nie über deren Eigenschaften zu.
  • Dies gewährleistet, dass nichts Ungewolltes verändert wird!. Deshalb sind sie ja private!
  • Nur innerhalb des Objektes selbst verändert man die eigenen Eigenschaften direkt.

Übung
  1. Schreiben Sie die Methode holeEinzug (double pBetrag, Konto pZielkonto),
    bei dem das Geld von einem fremden Konto überwiesen wird.
  2. Schreiben Sie die Methode vererben (Konto erbe),
    bei dem das gesamte Geld eines Kontos auf ein anderes verbucht wird.
  3. Schreiben Sie die Methode binIchReich(Konto vergleichskonto),
    das die Differenz aus dem eigenen Kontostand mit einem anderen Konto vergleicht.
  4. Schreiben Sie die Methode stifteVerwirrung(Konto konto1, Konto konto2),
    bei der ein unbeteiligtes Konto dafür sorgt, dass das gesamte Geld von konto1 auf konto2 überwiesen wird.
  5. Schreiben Sie die Methode stifteNochMehrVerwirrung(Konto konto1, Konto konto2),
    bei der ein unbeteiligtes Konto dafür sorgt, dass das gesamte Geld von konto1 halbiert, das von konto2 aber verdoppelt wird.
  6. Lassen Sie von einem Konto den Namen des Besitzers eines anderen Kontos ändern. Welche Probleme ergeben sich, wenn Sie die Methode setBesitzerName weglassen?


Weitere Beispiele

Der Zähler

  • Der Zähler ist eine einfache Klasse, bei dem Sie bei Aufruf der Methode erhoeheZaehlerstand() den Zähler um 1 erhöhen.
  • Anwendungen: Verkehrszählungen, Heizungsverbrauchzähler, Bildzähler bei einer Kamera, Rundenzähler bei der Carrera-Bahn...
  • Bei den realen Anwendungen kommt der Impuls von einem Sensor bzw. einen Druckknopf. Bei der Simulation müssen Sie statt dessen eine Methode ausführen.
 
public class Zaehler{
    // Instanzvariablen der Eigenschaften
    int zaehlerstand;
    // Konstruktor
    public Zaehler(){  
        // Der Anfangszählerstand soll immer 0 sein.
        zaehlerstand=0;
    }
    // Methoden
    public void erhoeheZaehlerstand(){
        zaehlerstand += 1;
        // oder zaehlerstand++;
        // oder zaehlerstand=zaehlerstand+1;
    }
}

Das Telefonbuch

Klassendiagramm-Telefonbuch.png
  • Die Telefonnummer wird, obwohl sie laut Name eine Nummer ist, als String eingelesen, um Eingaben wie „/“ zwischen Vorwahl und Nummer zuzulassen.
  • Die Besonderheit an dieser Klasse ist, dass name nur durch den Konstruktor verändert werden kann. D.h. ich kann zwar mit setTelefonnummer nachträglich Telefonnummern ändern, aber der Name bleibt erhalten.
  • Allenfalls durch das Löschen des Objektes kann ich Personen aus dem Telefonbuch entfernen.
public class Telefonbuch {
    // Eigenschaften

    // Anfang Variablen
    public String name;
    public String telefonnummer;
    // Ende Variablen

    // Konstruktor
    public Telefonbuch(String name, String telefonnummer) {
        // ... Hier fehlen 2 Zeilen. Bitte nachtragen! (vgl. Übung)
    }

    // Anfang Ereignisprozeduren
    // Methoden
    public String getTelefonnummer() {
        return telefonnummer;
    }

    public void setTelefonnummer(String pTelefonnummer) {
        telefonnummer = pTelefonnummer;
    }

    public String getName() {
        return name;
    }
    // Ende Ereignisprozeduren
}}

Das Auto

Klassendiagramm-Auto.png

Die Klasse simuliert ein Auto, erfasst aber nur Daten um den Tank und den Verbrauch.

  • Die manipulierenden Methoden tanke(..) und fahre(...) beeinflussen den aktuellen Füllstand.
  • Die sondierende Methode getAktuelleMaximaleReichweite gibt die Reichweite in km zurück, der beim aktuellen Füllstand noch gefahren werden kann.
  • Die Probleme der Klasse liegen noch darin, dass man (über das Tankvolumen hinaus) soviel tanken kann wie man will und dass der Tankinhalt auch in den negativen Bereich fahren kann (Dispokredit bei der Tankstelle). Das können wir erst lösen, wenn wir die bedingte Ausführung kennen gelernt haben.
public class Auto {
    private double volumenTank;
    private double verbrauchAuf100km;
    private double aktuellerFuellstand;

    // Konstruktor
    public Auto(double pVolumenTank, double pVerbrauchAuf100km) {
        volumenTank = pVolumenTank;
        verbrauchAuf100km = pVerbrauchAuf100km;
        aktuellerFuellstand = 0; // Bei Auslieferung ist der Tank leer
    }

    // Methoden
    public void setAktuellerFuellstand(double pAktuellerFuellstand) {
        aktuellerFuellstand = pAktuellerFuellstand;
    }
    public double getAktuellerFuellstand() {
        return aktuellerFuellstand;
    }
    public double getVerbrauchAuf100km() {
        return verbrauchAuf100km;
    }
    public double getVolumenTank() {
        return volumenTank;
    }
    public void tanke(double menge) {
        this.aktuellerFuellstand+=menge; // füge Menge hinzu
    }
    public void fahre(double pKilometerZahl) {
        // Die Formel sagt folgendes aus:
        // vom aktuellen Füllstand wird abgezogen: der Verbruch bei der Kilometerzahl  
        aktuellerFuellstand -= pKilometerZahl / 100 * verbrauchAuf100km; 
    }  
}


Übung
  1. Analysieren und testen Sie alle 3 Programme. Warum bekommt nicht jede Eigenschaft eine get- und eine set-Methode?
  2. Zu Zähler:
    1. Ergänzen Sie die Methode: getZaehlerstand()
    2. Ergänzen Sie die Methode: aufNullSetzen() und erhöheUm(double pZahl)
  3. Zu Telefonbuch: Ergänzen Sie die fehlenden Zeilen zum Konstruktor.
    1. Ergänzen Sie die Eigenschaften geburtsdatum (ggf. noch schuhgrösse).
    2. Welchen Datentypen verwenden Sie?
    3. Benötigt die Eigenschaft eine set-Methode?
  4. Zum Auto: Ergänzen Sie die Methode: getMaximaleReichweiteBeiVollemTank()
  5. Entwickeln Sie die Klasse Handy, die die Eigenschaften telefonnummer, guthaben und gespraechskostenProMinute. Entwickeln Sie geeignete Methoden.
  6. Übung für Fortgeschrittene: Realisieren Sie die Klasse Bruch mit den Eigenschaften zaehler und nenner und realisieren Sie die Methoden addierenEinerGanzenZahl, kuerzen und erweitern. Wenn Sie schon Vorwissen haben, können Sie hier für eine erweiterte Variante schauen: Anwendungsbeispiel Bruchrechnung (drdanielappel.de)


Weblinks