Inhaltsverzeichnis

  • Objektorientierte Programmierung (OOP)

    • Klassen und Objekte mit UML

    • Klassen und Objekte mit Java

    • Konstruktoren

    • Überladen von Konstruktoren

    • Überladen von Methoden

    • Kapselung

    • Kommentieren von Methoden

    • Gesamter bisheriger Code


Objektorientierte Programmierung (OOP)

Das Konzept der objektorientierten Programmierung lehnt sich an unsere Wahrnehmung der realen Welt an: wir strukturieren die Welt in Objekte und die damit verbundenen Attribute und Fähigkeiten.

So können wir alle Objekte vom Typ Auto als solche erkennen und können einem konkreten Auto sinnvolle Attribute, wie Farbe, Anzahl der Türen, etc. zuweisen. Eine Fähigkeit eines Autos wäre beispielsweise das Fahren oder das Öffnen einer Türe.

Ein weiteres wichtiges Konzept ist die Kapselung: Wenn wir beim Beispiel eines Autos bleiben, so ist es für einen Benutzer nicht wichtig zu wissen, wie der Motor oder das Getriebe funktioniert - es genügt, dem Fahrer ein Lenkrad und drei Pedale zur Verfügung zu stellen. Wie die internen Abläufe im Inneren des Autos hingegen aussehen und zusammenspielen bleibt für den normalen Fahrer unsichtbar. Diese Interna sind somit gekapselt, also versteckt. Nur über freigegebene Steuerungsmöglichkeiten ist eine Einflussnahme auf das Objekt möglich (hier z. B. durch die drei Pedale und das Lenkrad).

In der objektorientierten Programmierung (kurz OOP) wird diese für uns natürliche Strukturierung mit Attributen und Fähigkeiten sowie der Möglichkeit der Kapselung von Informationen zur Verfügung gestellt. Darüber hinaus ist sogar die Vererbung von Eigenschaften und Fähigkeiten möglich, als auch die Bereitstellung von Schnittstellen (Interfaces) zur Zusammenarbeit zwischen verschiedenen Objekten.

== Objektorientierte Programmierung (OOP) Das Konzept der _objektorientierten Programmierung_ lehnt sich an unsere Wahrnehmung der realen Welt an: wir strukturieren die Welt in Objekte und die damit verbundenen Attribute und Fähigkeiten. So können wir alle Objekte vom Typ Auto als solche erkennen und können einem konkreten Auto sinnvolle _Attribute_, wie Farbe, Anzahl der Türen, etc. zuweisen. Eine _Fähigkeit_ eines Autos wäre beispielsweise das Fahren oder das Öffnen einer Türe. Ein weiteres wichtiges Konzept ist die _Kapselung_: Wenn wir beim Beispiel eines Autos bleiben, so ist es für einen Benutzer nicht wichtig zu wissen, wie der Motor oder das Getriebe funktioniert - es genügt, dem Fahrer ein Lenkrad und drei Pedale zur Verfügung zu stellen. Wie die internen Abläufe im Inneren des Autos hingegen aussehen und zusammenspielen bleibt für den normalen Fahrer unsichtbar. Diese Interna sind somit _gekapselt_, also versteckt. Nur über freigegebene Steuerungsmöglichkeiten ist eine Einflussnahme auf das Objekt möglich (hier z. B. durch die drei Pedale und das Lenkrad). In der objektorientierten Programmierung (kurz OOP) wird diese für uns natürliche Strukturierung mit Attributen und Fähigkeiten sowie der Möglichkeit der Kapselung von Informationen zur Verfügung gestellt. Darüber hinaus ist sogar die Vererbung von Eigenschaften und Fähigkeiten möglich, als auch die Bereitstellung von Schnittstellen (_Interfaces_) zur Zusammenarbeit zwischen verschiedenen Objekten.

Klassen und Objekte mit UML

=== Klassen und Objekte mit UML

Die Grundbegriffe der OOP werden in den folgenden Kapiteln anhand eines Zoo-Großhandels eingeführt. Dieser Großhandel vertreibt die unterschiedlichsten Tiere und führt diese in einer Datenbank.

Als erste gehandelte Tierart betrachten wir den Löwen. Um einen Löwen zu beschreiben, könnte man ihm einen Namen geben, das Gewicht wäre noch interessant, vielleicht seine Futterzeiten und natürlich die Shampoo-Marke, die stets für eine glänzende Mähne im Showroom sorgt.

Um zu wissen, wie viele Pfoten in unserem Großhandel jeden Tag gepflegt werden müssen und um die zugehörigen Arbeiten entsprechend zu planen, soll auch noch die Anzahl der Beine des Löwen gespeichert werden.

Natürlich gibt es noch viele weitere Attribute, wie z. B. das Geburtsdatum, aber wir wollen die Beschreibung auf die oben erwähnten Punkte beschränken.

Damit hätte man einen Löwen schon ganz gut beschrieben, allerdings kann ein Löwe auch noch einiges tun, z. B. brüllen (in einer bestimmten Lautstärke) und laufen.

Die Grundbegriffe der OOP werden in den folgenden Kapiteln anhand eines Zoo-Großhandels eingeführt. Dieser Großhandel vertreibt die unterschiedlichsten Tiere und führt diese in einer Datenbank. Als erste gehandelte Tierart betrachten wir den Löwen. Um einen Löwen zu beschreiben, könnte man ihm einen *Namen* geben, das *Gewicht* wäre noch interessant, vielleicht seine *Futterzeiten* und natürlich die *Shampoo-Marke*, die stets für eine glänzende Mähne im Showroom sorgt. Um zu wissen, wie viele Pfoten in unserem Großhandel jeden Tag gepflegt werden müssen und um die zugehörigen Arbeiten entsprechend zu planen, soll auch noch die *Anzahl der Beine* des Löwen gespeichert werden. Natürlich gibt es noch viele weitere _Attribute_, wie z. B. das Geburtsdatum, aber wir wollen die Beschreibung auf die oben erwähnten Punkte beschränken. Damit hätte man einen Löwen schon ganz gut beschrieben, allerdings kann ein Löwe auch noch einiges _tun_, z. B. brüllen (in einer bestimmten Lautstärke) und laufen.

Man könnte diese Attribute und Fähigkeiten, die zu einem Löwen gehören, schematisch folgendermaßen darstellen, wobei wir bei allen Attributen und Fähigkeiten noch die jeweils sinnvollen Java-Typen dazuschreiben:

Man könnte diese _Attribute_ und _Fähigkeiten_, die zu einem Löwen gehören, schematisch folgendermaßen darstellen, wobei wir bei allen Attributen und Fähigkeiten noch die jeweils sinnvollen Java-Typen dazuschreiben:

Eine solche Darstellung der Klasse Loewe, aus der sich Objekte vom Typ Loewe erstellen lassen, wird auch mit der "Unified Modeling Language" (UML) so visualisiert:

Eine solche Darstellung der _Klasse_ Loewe, aus der sich _Objekte_ vom _Typ_ Loewe erstellen lassen, wird auch mit der "Unified Modeling Language" (UML) so visualisiert:

Die Attribute einer Klasse (also beispielsweise futterzeit, name, …​) werden in der OOP als Felder bezeichnet, die Funktionen als Methoden.

[NOTE] ==== Die Attribute einer Klasse (also beispielsweise futterzeit, name, ...) werden in der OOP als _Felder_ bezeichnet, die Funktionen als _Methoden_. ====

Klassen und Objekte mit Java

=== Klassen und Objekte mit Java

Wie sieht nun eine solche Definition der Klasse Loewe in Java aus?

Dazu muss eine Datei namens Loewe.java erstellt werden (der Name der Datei ist durch den Namen der Klasse festgelegt), die den folgenden Inhalt enthält:

Wie sieht nun eine solche Definition der _Klasse_ Loewe in Java aus? Dazu muss eine Datei namens *_Loewe.java_* erstellt werden (der Name der Datei ist durch den Namen der Klasse festgelegt), die den folgenden Inhalt enthält:
public class Loewe {

    public String name;
    public double gewicht;
    public String futterzeit;
    public String maehnenShampooMarke;
    public int anzahlBeine;

    public void laufe() {}

    public void bruelle(int dezibel) {}

}
Java
[source,java,indent=0] ---- public class Loewe { public String name; public double gewicht; public String futterzeit; public String maehnenShampooMarke; public int anzahlBeine; public void laufe() {} public void bruelle(int dezibel) {} } ----

Wunderbar, nun haben wir also die Klasse Loewe erstellt. Aber wie erstellt man daraus nun ein Objekt vom Typ Loewe, also z. B. den Löwen "Leo"?

Dazu erstellen wir beispielsweise im gleichen Verzeichnis eine weitere Datei namens Zoohandlung.java, die den folgenden Code enthält:

Wunderbar, nun haben wir also die _Klasse_ Loewe erstellt. Aber wie erstellt man daraus nun ein _Objekt_ vom Typ _Loewe_, also z. B. den Löwen "Leo"? Dazu erstellen wir beispielsweise im gleichen Verzeichnis eine weitere Datei namens *_Zoohandlung.java_*, die den folgenden Code enthält:
public class Zoohandlung {

    public static void main(String[] s) {
        Loewe leo = new Loewe(); (1)
        leo.name = "Leo, der Chef"; (2)
        leo.futterzeit = "12:00";
        leo.gewicht = 123.41;
        leo.maehnenShampooMarke = "Leoglanz Power 2";

        Loewe leonie = new Loewe(); (3)
        leonie.name = "Leonie, die Bissige"; (4)
        leonie.futterzeit = "13:00";
        leonie.gewicht = 110.12;
        leonie.maehnenShampooMarke = "Leoglanz Power 2 for girls";
    }
}
[indent=0] ---- public class Zoohandlung { public static void main(String[] s) { Loewe leo = new Loewe(); // <1> leo.name = "Leo, der Chef"; // <2> leo.futterzeit = "12:00"; leo.gewicht = 123.41; leo.maehnenShampooMarke = "Leoglanz Power 2"; Loewe leonie = new Loewe(); // <3> leonie.name = "Leonie, die Bissige"; //<4> leonie.futterzeit = "13:00"; leonie.gewicht = 110.12; leonie.maehnenShampooMarke = "Leoglanz Power 2 for girls"; } } ----
1 Hier wird ein neues Objekt vom Typ Loewe erstellt und eine Referenz darauf in der Variablen namens leo gespeichert. new erzeugt aus einer Klasse ein neues Objekt; der Typ des neuen Objekts und somit auch der Variablen leo ist hier Loewe.
2 Der Name des in der Variablen leo gespeicherten Löwen wird auf "Leo, der Chef" gesetzt.
3 Hier wird wieder ein neues Objekt vom Typ Loewe erstellt, dieses Mal aber in einer Variablen namens leonie gespeichert.
4 Hier wird der Name der Löwin festgelegt.
<1> Hier wird ein neues Objekt vom Typ _Loewe_ erstellt und *eine Referenz darauf* in der Variablen namens `leo` gespeichert. `new` erzeugt aus einer Klasse ein neues Objekt; der Typ des neuen Objekts und somit auch der Variablen `leo` ist hier _Loewe_. <2> Der Name des in der Variablen `leo` gespeicherten Löwen wird auf "Leo, der Chef" gesetzt. <3> Hier wird wieder ein neues Objekt vom Typ _Loewe_ erstellt, dieses Mal aber in einer Variablen namens `leonie` gespeichert. <4> Hier wird der Name der Löwin festgelegt.

Unterschied zwischen Klasse und Objekt

Die Klasse stellt den Bauplan für ein Objekt dar. Erst durch das Schlüsselwort new, das im Beispiel vorgestellt wurde, kann man aus dieser Bauanleitung ein konkretes Objekt erzeugen.

Aus einer Klasse kann man beliebig viele Objekte erzeugen.

[NOTE] ==== *Unterschied zwischen _Klasse_ und _Objekt_* Die _Klasse_ stellt den Bauplan für ein _Objekt_ dar. Erst durch das Schlüsselwort `new`, das im Beispiel vorgestellt wurde, kann man aus dieser Bauanleitung ein konkretes Objekt erzeugen. Aus einer Klasse kann man beliebig viele Objekte erzeugen. ====

Unter Punkt 1 wurde erwähnt, dass durch die Zeile

Loewe leo = new Loewe();

eine Referenz auf das neu erstellte Objekt vom Typ Loewe in der Variablen leo gespeichert wird. Dies wird an dem folgenden Beispiel deutlich:

[WARNING] ==== Unter Punkt 1 wurde erwähnt, dass durch die Zeile ---- Loewe leo = new Loewe(); ---- eine *Referenz* auf das neu erstellte Objekt vom Typ _Loewe_ in der Variablen `leo` gespeichert wird. Dies wird an dem folgenden Beispiel deutlich: ====
Loewe loewe = new Loewe();
Loewe loewe2 = loewe; (1)
System.out.println(loewe2.anzahlBeine);
loewe.anzahlBeine = 4; (2)
System.out.println(loewe2.anzahlBeine); (3)
loewe2.anzahlBeine = 6; (4)
System.out.println(loewe.anzahlBeine); (5)
loewe = null; (6)
System.out.println(loewe2.anzahlBeine); (7)
[indent=0] ---- Loewe loewe = new Loewe(); Loewe loewe2 = loewe; //<1> System.out.println(loewe2.anzahlBeine); loewe.anzahlBeine = 4; //<2> System.out.println(loewe2.anzahlBeine); //<3> loewe2.anzahlBeine = 6; //<4> System.out.println(loewe.anzahlBeine); //<5> loewe = null; //<6> System.out.println(loewe2.anzahlBeine); //<7> ----
1 In loewe2 wird eine weitere Referenz auf das Objekt gespeichert, auf das bereits loewe verweist. Es wird keine Kopie vom Objekt, auf das loewe verweist, in loewe2 gespeichert, sondern nur ein weiterer Zeiger auf das bereits bestehende Objekt.
2 Es wird die Anzahl der Beine des Objekts, auf das loewe verweist, auf 4 gesetzt.
3 Da es sich dabei um das selbe Objekt handelt, auf das auch loewe2 verweist, werden auch für loewe2 4 Beine ausgegeben.
4 Ebenso kann man die Anzahl der Beine auch über loewe2 verändern, was sich auch bei der Ausgabe von
5 der Anzahl der Beine von loewe niederschlägt.
6 Hier lässt man loewe auf null verweisen, also auf kein bestehendes Objekt mehr. Dadurch wurde unser Objekt jedoch nicht gelöscht, sondern man kann über
7 loewe2 noch darauf zugreifen.
<1> In `loewe2` wird eine weitere Referenz auf das Objekt gespeichert, auf das bereits `loewe` verweist. *Es wird keine Kopie vom Objekt, auf das `loewe` verweist, in `loewe2` gespeichert, sondern nur ein weiterer Zeiger auf das bereits bestehende Objekt.* <2> Es wird die Anzahl der Beine des Objekts, auf das `loewe` verweist, auf 4 gesetzt. <3> Da es sich dabei um das selbe Objekt handelt, auf das auch `loewe2` verweist, werden auch für `loewe2` 4 Beine ausgegeben. <4> Ebenso kann man die Anzahl der Beine auch über `loewe2` verändern, was sich auch bei der Ausgabe von <5> der Anzahl der Beine von `loewe` niederschlägt. <6> Hier lässt man `loewe` auf `null` verweisen, also auf kein bestehendes Objekt mehr. Dadurch wurde unser Objekt jedoch nicht gelöscht, sondern man kann über <7> `loewe2` noch darauf zugreifen.

Die Ausgabe des Programms ist somit:

Die Ausgabe des Programms ist somit:
0
4
6
6
---- 0 4 6 6 ----

Ein Objekt gilt dann als gelöscht, wenn keine Variable mehr darauf verweist.

All diese Objekte, auf die keine Referenz mehr besteht, werden im Hintergrund durch den sogenannten garbage collector (Müllsammler) aus dem Speicher gelöscht, der dadurch neuen Objekten zur Verfügung gestellt werden kann.

[NOTE] ==== Ein Objekt gilt dann als gelöscht, wenn keine Variable mehr darauf verweist. All diese Objekte, auf die keine Referenz mehr besteht, werden im Hintergrund durch den sogenannten *garbage collector* (Müllsammler) aus dem Speicher gelöscht, der dadurch neuen Objekten zur Verfügung gestellt werden kann. ====

Nachdem man ein Objekt aus einer Klasse erstellt hat, also beispielsweise das Objekt mit dem Bezeichner leo aus der Klasse Loewe, kann man über den Namen des Objekts auf die einzelnen Felder zugreifen, indem man hinter den Namen einen Punkt setzt und danach den entsprechenden Feldnamen.

Auf die gleiche Art und Weise kann man den Löwen brüllen und laufen lassen:

Nachdem man ein Objekt aus einer Klasse erstellt hat, also beispielsweise das Objekt mit dem Bezeichner leo aus der Klasse Loewe, kann man über den Namen des Objekts auf die einzelnen Felder zugreifen, indem man hinter den Namen einen Punkt setzt und danach den entsprechenden Feldnamen. Auf die gleiche Art und Weise kann man den Löwen brüllen und laufen lassen:
leo.bruelle(60);
leo.laufe();
Java
[source,java,indent=0] ---- leo.bruelle(60); leo.laufe(); ----

Das funktioniert soweit schon ganz gut, allerdings erscheint es etwas umständlich, die ganzen Informationen zu einem erstellten Löwen zeilenweise zu übergeben. Viel schöner wäre doch die Übergabe der Werte bereits beim Erstellen, also so etwas wie:

Loewe leo = new Loewe("Leo","13:00",123.21,4,"Leo Extra");
Java

Das sollen in der Reihenfolge der Name, die Futterzeit, das Gewicht, die Anzahl der Beine und schließlich der Name des Mähnenshampoos sein.

Und wir haben Glück, genau so etwas gibt es, nämlich die sogenannten Konstruktoren.

Das funktioniert soweit schon ganz gut, allerdings erscheint es etwas umständlich, die ganzen Informationen zu einem erstellten Löwen zeilenweise zu übergeben. Viel schöner wäre doch die Übergabe der Werte bereits beim Erstellen, also so etwas wie: [source,java,indent=0] ---- Loewe leo = new Loewe("Leo","13:00",123.21,4,"Leo Extra"); ---- Das sollen in der Reihenfolge der Name, die Futterzeit, das Gewicht, die Anzahl der Beine und schließlich der Name des Mähnenshampoos sein. Und wir haben Glück, genau so etwas gibt es, nämlich die sogenannten _Konstruktoren_.

Konstruktoren

=== Konstruktoren

Ein Konstruktor ist der Teil der Klasse, der beim Erstellen (englisch: to construct) eines Objekts aufgerufen wird. In Java sieht ein Konstruktor fast aus wie eine normale Methode, nur mit zwei Besonderheiten:

  1. Der Konstruktor muss so heißen wie die Klasse, in unserem Fall also Loewe.

  2. Es wird kein Rückgabewert festgelegt, d. h. es steht nicht mal void davor, sondern einfach nichts.

Der Konstruktor kann mehrere Argumente entgegennehmen, so dass beim Erstellen die entsprechenden Werte übergeben werden können. Um also einen Löwen mittels

Ein Konstruktor ist der Teil der Klasse, der beim Erstellen (englisch: to construct) eines Objekts aufgerufen wird. In Java sieht ein Konstruktor fast aus wie eine normale Methode, nur mit zwei Besonderheiten: . Der Konstruktor muss so heißen wie die Klasse, in unserem Fall also _Loewe_. . Es wird kein Rückgabewert festgelegt, d. h. es steht nicht mal `void` davor, sondern einfach *nichts*. Der Konstruktor kann mehrere Argumente entgegennehmen, so dass beim Erstellen die entsprechenden Werte übergeben werden können. Um also einen Löwen mittels
Loewe leo = new Loewe("Leo","13:00",123.21,4,"Leo Extra");
Java
[source,java,indent=0] ---- Loewe leo = new Loewe("Leo","13:00",123.21,4,"Leo Extra"); ----

erstellen zu können, brauchen wir einen Konstruktor mit folgender Signatur:

erstellen zu können, brauchen wir einen Konstruktor mit folgender Signatur:
Loewe(String name,String futterzeit,double gewicht,int anzahlBeine,String maehnenShampooMarke)
Java
[source,java,indent=0] ---- Loewe(String name,String futterzeit,double gewicht,int anzahlBeine,String maehnenShampooMarke) ----

Damit durch den Konstruktor auch die Felder des Objekts richtig belegt werden, müssen die Werte an sie übergeben werden. Dies ist folgendermaßen möglich:

Damit durch den Konstruktor auch die Felder des Objekts richtig belegt werden, müssen die Werte an sie übergeben werden. Dies ist folgendermaßen möglich:
public Loewe(String name, String futterzeit, double gewicht, int anzahlBeine, String msm){
    this.anzahlBeine=anzahlBeine;
    this.futterzeit=futterzeit;
    this.gewicht=gewicht;
    maehnenShampooMarke=msm;
    this.name=name;
}
Java
[source,java,indent=0] ---- public Loewe(String name, String futterzeit, double gewicht, int anzahlBeine, String msm){ this.anzahlBeine=anzahlBeine; this.futterzeit=futterzeit; this.gewicht=gewicht; maehnenShampooMarke=msm; this.name=name; } ----

Hier werden die übergebenen Argumente an den Konstruktor weitergegeben. In diesem Beispiel heißen die meisten Variablennamen der übergebenen Argumente genauso wie die Namen der Felder der Klasse Loewe selbst. So gibt es im Konstruktor ein Argument, das in der Variable name übergeben wird und nachher im Feld name gespeichert wird.

Damit sich die beiden Bezeichner mit dem gleichen Namen nicht in die Quere kommen, wird das zur Klasse gehörende Feld über das Schlüsselwort this eindeutig beschrieben. this verweist stets auf das Objekt, in dem man sich in dieser Programmzeile gerade befindet. So bewirkt die Zeile

this.anzahlBeine=anzahlBeine;
Java

dass das rechte in der Variablen anzahlBeine übergebene Argument an das Feld des aktuellen Objekts mit dem gleichen Namen übergeben wird, wobei dieses durch das Voranstellen von this. eindeutig gekennzeichnet ist.

Natürlich muss man den Namen des Parameters in der Signatur des Konstruktors nicht so wählen, wie der Feldname heißt. Aus Bequemlichkeit macht man das aber häufig.

Im obigen Beispiel findet sich auch die Zeile

maehnenShampooMarke=msm;
Java

Hier benötigt man kein this. vor dem maehnenShampooMarke, da hier keine Verwechslung möglich ist. Es ist klar, dass maehnenShampooMarke das Feld des aktuellen Objekts ist und msn der übergebene Parameter.

Hier werden die übergebenen Argumente an den Konstruktor weitergegeben. In diesem Beispiel heißen die meisten Variablennamen der übergebenen Argumente genauso wie die Namen der Felder der Klasse _Loewe_ selbst. So gibt es im Konstruktor ein Argument, das in der Variable `name` übergeben wird und nachher im Feld `name` gespeichert wird. Damit sich die beiden Bezeichner mit dem gleichen Namen nicht in die Quere kommen, wird das zur Klasse gehörende Feld über das Schlüsselwort `this` eindeutig beschrieben. `this` verweist stets auf das Objekt, in dem man sich in dieser Programmzeile gerade befindet. So bewirkt die Zeile [source,java,indent=0] ---- this.anzahlBeine=anzahlBeine; ---- dass das rechte in der Variablen `anzahlBeine` übergebene Argument an das Feld des aktuellen Objekts mit dem gleichen Namen übergeben wird, wobei dieses durch das Voranstellen von `this.` eindeutig gekennzeichnet ist. Natürlich muss man den Namen des Parameters in der Signatur des Konstruktors nicht so wählen, wie der Feldname heißt. Aus Bequemlichkeit macht man das aber häufig. Im obigen Beispiel findet sich auch die Zeile [source,java,indent=0] ---- maehnenShampooMarke=msm; ---- Hier benötigt man kein `this.` vor dem `maehnenShampooMarke`, da hier keine Verwechslung möglich ist. Es ist klar, dass `maehnenShampooMarke` das Feld des aktuellen Objekts ist und `msn` der übergebene Parameter.

Überladen von Konstruktoren

=== Überladen von Konstruktoren

Unsere Zoohandlung muss im Normalfall bei der Aufnahme eines neuen Löwen die Futterzeit, die Anzahl der Beine und die Shampoo-Marke nicht gesondert angeben, da sich diese Eigenschaften üblicherweise nicht ändern. Deshalb wäre es praktisch, einen Konstruktor der Signatur

Unsere Zoohandlung muss im Normalfall bei der Aufnahme eines neuen Löwen die Futterzeit, die Anzahl der Beine und die Shampoo-Marke nicht gesondert angeben, da sich diese Eigenschaften üblicherweise nicht ändern. Deshalb wäre es praktisch, einen Konstruktor der Signatur
Loewe(String name, double gewicht)
Java
[source,java,indent=0] ---- Loewe(String name, double gewicht) ----

zur Verfügung zu haben und die anderen Werte mit Standardwerten zu belegen.

Wir werden diesen Konstruktor also auch anlegen, den bisherigen aber lassen. Dadurch gibt es zwei Konstruktoren für Loewe:

zur Verfügung zu haben und die anderen Werte mit Standardwerten zu belegen. Wir werden diesen Konstruktor also auch anlegen, den bisherigen aber lassen. Dadurch gibt es zwei Konstruktoren für _Loewe_:
Loewe(String name, double gewicht)
Java
[source,java,indent=0] ---- Loewe(String name, double gewicht) ----
Loewe(String name,String futterzeit,double gewicht,int anzahlBeine,String maehnenShampooMarke)
Java
[source,java,indent=0] ---- Loewe(String name,String futterzeit,double gewicht,int anzahlBeine,String maehnenShampooMarke) ----

Der Java-Compiler hat damit jedoch kein Problem, da beim Aufrufen der Konstruktoren aufgrund der Typen der übergebenen Argumente klar wird, welcher herangezogen werden muss:

Der Java-Compiler hat damit jedoch kein Problem, da beim Aufrufen der Konstruktoren aufgrund der Typen der übergebenen Argumente klar wird, welcher herangezogen werden muss:
Loewe leo = new Loewe("Leo",123.2);
Loewe leonie = new Loewe("Leonie","14:00",121.1,4,"Lioness Gold");
Java
[source,java,indent=0] ---- Loewe leo = new Loewe("Leo",123.2); Loewe leonie = new Loewe("Leonie","14:00",121.1,4,"Lioness Gold"); ----

Im ersten Fall wird erst ein String und dann eine double-Zahl übergeben, also kommt nur der Konstruktor Loewe(String name, double gewicht) dafür in Frage, der zweite Aufruf passt dafür genau auf den anderen Konstruktor.

Würde man zusätzlich noch einen Konstruktor wie Loewe(String futterzeit, double gewicht) einführen, so käme es zu einer Fehlermeldung, da der Compiler bei einem Aufruf von

Loewe leo = new Loewe("Leo",123.2);

nicht entscheiden kann, welchen Konstruktor er wählen soll:

Loewe(String futterzeit, double gewicht)

oder

Loewe(String name, double gewicht)?

Beide erwarten an erster Stelle einen String und dann einen double-Wert. Ein solcher Fall darf nicht auftreten!

Im ersten Fall wird erst ein String und dann eine double-Zahl übergeben, also kommt nur der Konstruktor `Loewe(String name, double gewicht)` dafür in Frage, der zweite Aufruf passt dafür genau auf den anderen Konstruktor. [WARNING] ==== Würde man zusätzlich noch einen Konstruktor wie `Loewe(String futterzeit, double gewicht)` einführen, so käme es zu einer Fehlermeldung, da der Compiler bei einem Aufruf von `Loewe leo = new Loewe("Leo",123.2);` nicht entscheiden kann, welchen Konstruktor er wählen soll: `Loewe(String futterzeit, double gewicht)` oder `Loewe(String name, double gewicht)`? Beide erwarten an erster Stelle einen String und dann einen double-Wert. Ein solcher Fall darf nicht auftreten! ====

Loewe(String futterzeit, double gewicht)

Loewe(String name, double gewicht)

`Loewe(String futterzeit, double gewicht)` `Loewe(String name, double gewicht)`

Loewe leo = new Loewe("Leo",123.2);

`Loewe leo = new Loewe("Leo",123.2);`

Man bezeichnet die Möglichkeit, mehrere Konstruktoren gleichen Namens - jedoch mit unterschiedlichen Typen - verwenden zu können, als Überladen von Konstruktoren.

Eine Implementierung der beiden Konstruktoren könnte folgendermaßen aussehen:

Man bezeichnet die Möglichkeit, mehrere Konstruktoren gleichen Namens - jedoch mit unterschiedlichen Typen - verwenden zu können, als *Überladen von Konstruktoren*. Eine Implementierung der beiden Konstruktoren könnte folgendermaßen aussehen:
public Loewe(String name, String futterzeit, double gewicht, int anzahlBeine, String msm) {
    this.anzahlBeine = anzahlBeine;
    this.futterzeit = futterzeit;
    this.gewicht = gewicht;
    maehnenShampooMarke = msm;
    this.name = name;
}

public Loewe(String name, double gewicht) {
    this.gewicht = gewicht;
    this.name = name;
}
Java
[source,java,indent=0] ---- public Loewe(String name, String futterzeit, double gewicht, int anzahlBeine, String msm) { this.anzahlBeine = anzahlBeine; this.futterzeit = futterzeit; this.gewicht = gewicht; maehnenShampooMarke = msm; this.name = name; } public Loewe(String name, double gewicht) { this.gewicht = gewicht; this.name = name; } ----

Für die restlichen Werte (Gewicht, Futterzeit und Anzahl der Beine) müssen dazu Standardwerte in der Klasse festgelegt werden, also z. B.

Für die restlichen Werte (Gewicht, Futterzeit und Anzahl der Beine) müssen dazu Standardwerte in der Klasse festgelegt werden, also z. B.
public String name;
public double gewicht;
public String futterzeit = "13:00";
public String maehnenShampooMarke = "LeoGlanz Power 2";
public int anzahlBeine = 4;
Java
[source,java,indent=0] ---- public String name; public double gewicht; public String futterzeit = "13:00"; public String maehnenShampooMarke = "LeoGlanz Power 2"; public int anzahlBeine = 4; ----

Übrigens gibt es noch eine letzte Möglichkeit, die Erstellung der Konstruktoren zu optimieren. Im letzten Beispiel weisen beide Konstruktoren den Feldern gewicht und name ihre Werte zu. Insofern liegt hier doppelter Code vor, der zweimal das Gleiche macht.

Eine Möglichkeit, dies zu umgehen, wäre die folgende Vorgehensweise beim zweiten Konstruktor:

Übrigens gibt es noch eine letzte Möglichkeit, die Erstellung der Konstruktoren zu optimieren. Im letzten Beispiel weisen beide Konstruktoren den Feldern `gewicht` und `name` ihre Werte zu. Insofern liegt hier doppelter Code vor, der zweimal das Gleiche macht. Eine Möglichkeit, dies zu umgehen, wäre die folgende Vorgehensweise beim zweiten Konstruktor:
public Loewe(String name, String futterzeit, double gewicht, int anzahlBeine, String msm) {
    this(name,gewicht);
    this.futterzeit = futterzeit;
    this.anzahlBeine = anzahlBeine;
    maehnenShampooMarke = msm;
}
Java
[source,java,indent=0] ---- public Loewe(String name, String futterzeit, double gewicht, int anzahlBeine, String msm) { this(name,gewicht); this.futterzeit = futterzeit; this.anzahlBeine = anzahlBeine; maehnenShampooMarke = msm; } ----

Mit this(name,gewicht) wird der Konstruktor Loewe(String name, double gewicht) aufgerufen.

Das funktioniert allerdings nur, wenn dies in der ersten Zeile eines Konstruktors geschieht. Sonst darf ein Konstruktor keinen anderen Konstruktor aufrufen.

Mit `this(name,gewicht)` wird der Konstruktor `Loewe(String name, double gewicht)` aufgerufen. Das funktioniert allerdings nur, wenn dies in der ersten Zeile eines Konstruktors geschieht. Sonst darf ein Konstruktor keinen anderen Konstruktor aufrufen.

Überladen von Methoden

=== Überladen von Methoden

Ebenso wie Konstruktoren lassen sich auch Methoden überladen: neben

public void bruelle(int dezibel)

könnte also beispielsweise problemlos noch

public void bruelle(int dezibel, int dauer)

definiert werden.

Auch hier ist zu beachten, dass die Signaturen nicht identisch sein dürfen:

public void bruelle(int dezibel) und public void bruelle(int dauer) haben aus Sicht des Compilers identische Signaturen, da sie beide gleich heißen und jeweils genau einen Parameter vom Typ int erwarten. Das würde somit zu einem Compiler-Fehler führen.

Ebenso wie Konstruktoren lassen sich auch Methoden überladen: neben ---- public void bruelle(int dezibel) ---- könnte also beispielsweise problemlos noch ---- public void bruelle(int dezibel, int dauer) ---- definiert werden. Auch hier ist zu beachten, dass die Signaturen nicht identisch sein dürfen: `public void bruelle(int dezibel)` und `public void bruelle(int dauer)` haben aus Sicht des Compilers identische Signaturen, da sie beide gleich heißen und jeweils genau einen Parameter vom Typ `int` erwarten. Das würde somit zu einem Compiler-Fehler führen.

Kapselung

=== Kapselung

Angenommen, wir geben unser bisheriges Programm an eine andere Zoohandlung weiter. Diese ist begeistert und fängt sofort an, damit zu arbeiten.

Bei der ersten Benutzung schleicht sich leider ein Fehler ein, da ein Löwe fälschlicherweise folgendermaßen erstellt wird:

Angenommen, wir geben unser bisheriges Programm an eine andere Zoohandlung weiter. Diese ist begeistert und fängt sofort an, damit zu arbeiten. Bei der ersten Benutzung schleicht sich leider ein Fehler ein, da ein Löwe fälschlicherweise folgendermaßen erstellt wird:
Loewe leo = new Loewe();
leo.anzahlBeine = -4;
Java
[source,java,indent=0] ---- Loewe leo = new Loewe(); leo.anzahlBeine = -4; ----

Für die Anzahl der Beine wird also eine negative Zahl eingegeben. Unser Programm lässt das bisher zu, aber natürlich ergibt das keinen Sinn. Sollte der Fehler unbemerkt bleiben und die Fußpediküre für alle Tiere eingeteilt werden, so kann es hier zu Problemen im weiteren Ablauf in der anderen Zoohandlung kommen.

Erkenntnis:

Es ist nicht sinnvoll, dass andere Benutzer unseres Programms Felder von Objekten direkt ändern können. Wenn wir die korrekte Funktionsweise unseres Programms gewährleisten wollen, müssen wir verhindern, dass solche direkten Abänderungen vorgenommen werden können.

Ähnlich verhält es sich heutzutage bei vielen Motoren von Fahrzeugen etablierter Automobilhersteller. Anstatt beim Öffnen der Motorhaube Zugriff auf den gesamten Motor zu erhalten, befindet sich dort häufig ein versiegelter Motorblock mit einem Diagnoseanschluss. Nur der Ölstand und das Kühlwasser lassen sich noch regeln.

Ähnlich sollte auch unsere Klasse in der Lage sein, interne Felder vor äußerem Zugriff zu Schützen, diese Informationen von der Außenwelt also zu kapseln.

Für die Anzahl der Beine wird also eine negative Zahl eingegeben. Unser Programm lässt das bisher zu, aber natürlich ergibt das keinen Sinn. Sollte der Fehler unbemerkt bleiben und die Fußpediküre für alle Tiere eingeteilt werden, so kann es hier zu Problemen im weiteren Ablauf in der anderen Zoohandlung kommen. ==== *Erkenntnis:* Es ist nicht sinnvoll, dass andere Benutzer unseres Programms Felder von Objekten direkt ändern können. Wenn wir die korrekte Funktionsweise unseres Programms gewährleisten wollen, müssen wir verhindern, dass solche direkten Abänderungen vorgenommen werden können. ==== [NOTE] ==== Ähnlich verhält es sich heutzutage bei vielen Motoren von Fahrzeugen etablierter Automobilhersteller. Anstatt beim Öffnen der Motorhaube Zugriff auf den gesamten Motor zu erhalten, befindet sich dort häufig ein versiegelter Motorblock mit einem Diagnoseanschluss. Nur der Ölstand und das Kühlwasser lassen sich noch regeln. Ähnlich sollte auch unsere Klasse in der Lage sein, interne Felder vor äußerem Zugriff zu Schützen, diese Informationen von der Außenwelt also zu kapseln. ====

Die Sichtbarkeit von Feldern und Methoden lassen sich über die Sichtbarkeitsmodifikatoren public, private und protected steuern, wobei wir zunächst die beiden zuerst genannten betrachten:

public bedeutet, dass auf diese Felder auch von außerhalb der Klasse zugegriffen werden kann, so wie es in den bisherigen Beispielen der Fall war. Mit Hilfe des Schlüsselworts private unterbinden wir den Zugriff von außen.

So ändern wir

Die Sichtbarkeit von Feldern und Methoden lassen sich über die _Sichtbarkeitsmodifikatoren_ `public`, `private` und `protected` steuern, wobei wir zunächst die beiden zuerst genannten betrachten: `public` bedeutet, dass auf diese Felder auch von außerhalb der Klasse zugegriffen werden kann, so wie es in den bisherigen Beispielen der Fall war. Mit Hilfe des Schlüsselworts `private` unterbinden wir den Zugriff von außen. So ändern wir
public class Loewe {

    public String name;
    public double gewicht;
    public String futterzeit = "13:00";
    public String maehnenShampooMarke = "LeoGlanz Power 2";
    public int anzahlBeine = 4;
....
}
Java
[source,java,indent=0] ---- public class Loewe { public String name; public double gewicht; public String futterzeit = "13:00"; public String maehnenShampooMarke = "LeoGlanz Power 2"; public int anzahlBeine = 4; .... } ----

ab zu

ab zu
public class Loewe {

    private String name;
    private double gewicht;
    private String futterzeit = "13:00";
    private String maehnenShampooMarke = "LeoGlanz Power 2";
    private int anzahlBeine = 4;
....
}
Java
[source,java,indent=0] ---- public class Loewe { private String name; private double gewicht; private String futterzeit = "13:00"; private String maehnenShampooMarke = "LeoGlanz Power 2"; private int anzahlBeine = 4; .... } ----

und schon ergibt

und schon ergibt
Loewe leo = new Loewe("Leo",123.3);
leo.anzahlBeine = -4;
Java
[source,java,indent=0] ---- Loewe leo = new Loewe("Leo",123.3); leo.anzahlBeine = -4; ----

eine Fehlermeldung, da auf das Feld anzahlBeine nicht von außerhalb der Klasse Loewe zugegriffen werden kann (die obigen Zeilen befinden sich in der Klasse Zoohandlung, also in einer anderen Klasse als die Klasse Loewe).

Somit ist unser Feld vor unsachgemäßem Gebrauch hiermit geschützt.

Aber bedeutet das, dass man die Anzahl der Beine nach einer Verletzung des Löwen nicht mehr ändern kann?

Doch! Hierfür legt man beispielsweise gesonderte Getter und Setter fest.

eine Fehlermeldung, da auf das Feld `anzahlBeine` nicht von außerhalb der Klasse _Loewe_ zugegriffen werden kann (die obigen Zeilen befinden sich in der Klasse _Zoohandlung_, also in einer anderen Klasse als die Klasse _Loewe_). Somit ist unser Feld vor unsachgemäßem Gebrauch hiermit geschützt. Aber bedeutet das, dass man die Anzahl der Beine nach einer Verletzung des Löwen nicht mehr ändern kann? Doch! Hierfür legt man beispielsweise gesonderte _Getter_ und _Setter_ fest.

Getter und Setter

=== Getter und Setter

Bei Gettern und Settern handelt es sich um Methoden, die einen kontrollierten Zugriff auf private Felder erlauben. So könnte die Anzahl der Beine durch die folgenden Methoden gesetzt (Setter) und abgefragt werden (Getter):

Bei Gettern und Settern handelt es sich um Methoden, die einen kontrollierten Zugriff auf private Felder erlauben. So könnte die Anzahl der Beine durch die folgenden Methoden gesetzt (Setter) und abgefragt werden (Getter):
private int anzahlBeine = 4;

public void setAnzahlBeine(int anzahl) {
    if (anzahl >= 0) {
        anzahlBeine = anzahl;
    }
}

public int getAnzahlBeine() {
    return anzahlBeine;
}
Java
[source,java,indent=0] ---- private int anzahlBeine = 4; public void setAnzahlBeine(int anzahl) { if (anzahl >= 0) { anzahlBeine = anzahl; } } public int getAnzahlBeine() { return anzahlBeine; } ----

Hier sieht man, wie man den Zugriff auf ein privates Feld über öffentliche (public) Getter und Setter steuern kann. In diesem Fall wird beim Setzen der Beinanzahl überprüft, ob die übergebene Anzahl größer gleich 0 ist und diese nur dann im Feld gespeichert.

Natürlich könnte man nun auch Getter und Setter für die anderen Felder definieren, wir sparen uns das aber der Übersichtlichkeit halber.

Hier sieht man, wie man den Zugriff auf ein privates Feld über öffentliche (`public`) Getter und Setter steuern kann. In diesem Fall wird beim Setzen der Beinanzahl überprüft, ob die übergebene Anzahl größer gleich 0 ist und diese nur dann im Feld gespeichert. Natürlich könnte man nun auch Getter und Setter für die anderen Felder definieren, wir sparen uns das aber der Übersichtlichkeit halber.

Drückt man in Netbeans in einer Klasse bei gedrückter Steuerungstaste die Leertaste, so schlägt Netbeans automatisch die fehlenden Getter und Setter vor und erstellt die notwendigen Codezeilen bei entsprechender Auswahl.

Sehr praktisch!

[TIP] ==== Drückt man in *Netbeans* in einer Klasse bei gedrückter Steuerungstaste die Leertaste, so schlägt Netbeans automatisch die fehlenden Getter und Setter vor und erstellt die notwendigen Codezeilen bei entsprechender Auswahl. Sehr praktisch! ====

Grundansatz zur Kapselung:

Alle Felder einer Klasse sollten, sofern nicht gute Gründe dagegen sprechen, von ihrer Sichtbarkeit her auf private gesetzt werden und nur über öffentliche Methoden (z. B. Getter und / oder Setter) verändert oder ausgelesen werden.

==== *Grundansatz zur Kapselung:* Alle Felder einer Klasse sollten, sofern nicht gute Gründe dagegen sprechen, von ihrer Sichtbarkeit her auf `private` gesetzt werden und nur über öffentliche Methoden (z. B. Getter und / oder Setter) verändert oder ausgelesen werden. ====

Private Methoden

Auch Methoden können mit dem Sichtbarkeitsmodifikator private geschützt werden. Das ist häufig sinnvoll, denn Aufrufe von internen Berechnungen sollten von außen nicht zugänglich sein.

Dazu muss statt public einfach private vor die Methode geschrieben werden.

[NOTE] ==== *Private Methoden* Auch Methoden können mit dem _Sichtbarkeitsmodifikator_ `private` geschützt werden. Das ist häufig sinnvoll, denn Aufrufe von internen Berechnungen sollten von außen nicht zugänglich sein. Dazu muss statt `public` einfach `private` vor die Methode geschrieben werden. ====

In UML wird der Sichtbarkeitsmodifikator public mit einem vorangestellten + dargestellt, private hingegen mit einem -.

Hier das UML-Diagramm zum bisherigen Löwen:

In UML wird der Sichtbarkeitsmodifikator `public` mit einem vorangestellten `+` dargestellt, `private` hingegen mit einem `-`. Hier das UML-Diagramm zum bisherigen Löwen:

Kommentieren von Methoden

=== Kommentieren von Methoden

Um das Arbeiten mit Klassen und Objekten in Entwicklungsumgebungen komfortabler zu gestalten, sollte man seinen Code auch stets kommentieren, insbesondere Methoden. Der Vorteil besteht darin, dass in Entwicklungsumgebungen diese Kommentare direkt in der Vorschau zum Befehl erscheinen und dem Programmierer eine Idee vermitteln, was diese Methode eigentlich macht.

Das könnte beispielsweise so aussehen:

Um das Arbeiten mit Klassen und Objekten in Entwicklungsumgebungen komfortabler zu gestalten, sollte man seinen Code auch stets kommentieren, insbesondere Methoden. Der Vorteil besteht darin, dass in Entwicklungsumgebungen diese Kommentare direkt in der Vorschau zum Befehl erscheinen und dem Programmierer eine Idee vermitteln, was diese Methode eigentlich macht. Das könnte beispielsweise so aussehen:

Um diese Ausgabe zu erhalten, muss direkt über der Methode in der Klasse die entsprechende Beschreibung Eingang finden. Das würde in diesem Fall für die Methode bruelle(int dezibel) so aussehen:

Um diese Ausgabe zu erhalten, muss direkt über der Methode in der Klasse die entsprechende Beschreibung Eingang finden. Das würde in diesem Fall für die Methode `bruelle(int dezibel)` so aussehen:
/**
 * Lässt den Löwen brüllen, wobei die Lautstärke über dezibel gesteuert werden kann.
 * @param dezibel Lautstärke in Dezibel
 */
public void bruelle(int dezibel) {
    ...
}
Java
[source,java,indent=0] ---- /** * Lässt den Löwen brüllen, wobei die Lautstärke über dezibel gesteuert werden kann. * @param dezibel Lautstärke in Dezibel */ public void bruelle(int dezibel) { ... } ----

Netbeans hilft uns beim Erstellungsprozess von Kommentaren:

Sobald man direkt über einer Methode /** gefolgt von der Eingabetaste eingibt, erstellt Netbeans schon das Gerüst für den Kommentar inklusive aller Variablen.

Da die Namen der Parameter in die Dokumentation einfließen, sollten sie sprechende Namen sein: also im obigen Beispiel dezibel und nicht a.

Mehr Informationen zur Kommentierung von Klassen und deren Felder und Methoden findet man beispielsweise unter http://scalingbits.com/java/javakurs1/begleitend/javadoc.

[TIP] ==== Netbeans hilft uns beim Erstellungsprozess von Kommentaren: Sobald man direkt über einer Methode `/**` gefolgt von der Eingabetaste eingibt, erstellt Netbeans schon das Gerüst für den Kommentar inklusive aller Variablen. ==== [IMPORTANT] ==== Da die Namen der Parameter in die Dokumentation einfließen, sollten sie _sprechende Namen_ sein: also im obigen Beispiel `dezibel` und nicht `a`. ==== Mehr Informationen zur Kommentierung von Klassen und deren Felder und Methoden findet man beispielsweise unter http://scalingbits.com/java/javakurs1/begleitend/javadoc.

Gesamter bisheriger Code

Hier gibt es denn ganzen bisherigen Code.

=== Gesamter bisheriger Code <<tags_b,Hier gibt es denn ganzen bisherigen Code>>.

Loewe.java:

package zoohandlung;


public class Loewe {

    public String name;
    public double gewicht;
    public String futterzeit = "13:00";
    public String maehnenShampooMarke = "LeoGlanz Power 2";
    public int anzahlBeine = 4;

    public void laufe() {
        System.out.println("Ich laufe jetzt.");
    }

    public void bruelle(int dezibel) {
        System.out.println("Brüll");
        if (dezibel > 70) {
            System.out.println("BRÜLL!");
        }
    }

    public Loewe() {
    }

    public Loewe(String name, double gewicht) {
        this.name = name;
        this.gewicht = gewicht;
    }

    public Loewe(String name, String futterzeit, double gewicht, int anzahlBeine, String msm) {
        this.name = name;
        this.futterzeit = futterzeit;
        this.gewicht = gewicht;
        this.anzahlBeine = anzahlBeine;
        maehnenShampooMarke = msm;
    }

    public void setAnzahlBeine(int anzahl) {
        if (anzahl >= 0) {
            anzahlBeine = anzahl;
        }
    }

    public int getAnzahlBeine() {
        return anzahlBeine;
    }
}
Java
*Loewe.java:* [source,java,indent=0] ---- package zoohandlung; public class Loewe { public String name; public double gewicht; public String futterzeit = "13:00"; public String maehnenShampooMarke = "LeoGlanz Power 2"; public int anzahlBeine = 4; public void laufe() { System.out.println("Ich laufe jetzt."); } public void bruelle(int dezibel) { System.out.println("Brüll"); if (dezibel > 70) { System.out.println("BRÜLL!"); } } public Loewe() { } public Loewe(String name, double gewicht) { this.name = name; this.gewicht = gewicht; } public Loewe(String name, String futterzeit, double gewicht, int anzahlBeine, String msm) { this.name = name; this.futterzeit = futterzeit; this.gewicht = gewicht; this.anzahlBeine = anzahlBeine; maehnenShampooMarke = msm; } public void setAnzahlBeine(int anzahl) { if (anzahl >= 0) { anzahlBeine = anzahl; } } public int getAnzahlBeine() { return anzahlBeine; } } ----

Zoohandlung.java:

package zoohandlung;


public class Zoohandlung {

    public static void main(String[] s) {
        Loewe leo = new Loewe();
        leo.name = "Leo, der Chef";
        leo.futterzeit = "12:00";
        leo.gewicht = 123.41;
        leo.maehnenShampooMarke = "Leoglanz Power 2";

        leo.bruelle(60);
        leo.laufe();

        Loewe leonie = new Loewe();
        leonie.name = "Leonie, die Bissige";
        leonie.futterzeit = "13:00";
        leonie.gewicht = 110.12;
        leonie.maehnenShampooMarke = "Leoglanz Power 2 for girls";

        Loewe max=new Loewe("Max",132.32);
        max.bruelle(80);
        max.laufe();
    }
}
Java
*Zoohandlung.java:* [source,java,indent=0] ---- package zoohandlung; public class Zoohandlung { public static void main(String[] s) { Loewe leo = new Loewe(); leo.name = "Leo, der Chef"; leo.futterzeit = "12:00"; leo.gewicht = 123.41; leo.maehnenShampooMarke = "Leoglanz Power 2"; leo.bruelle(60); leo.laufe(); Loewe leonie = new Loewe(); leonie.name = "Leonie, die Bissige"; leonie.futterzeit = "13:00"; leonie.gewicht = 110.12; leonie.maehnenShampooMarke = "Leoglanz Power 2 for girls"; Loewe max=new Loewe("Max",132.32); max.bruelle(80); max.laufe(); } } ----

Wahlweise kann auch das zugehörige Netbeans-Projekt heruntergeladen werden:

Wahlweise kann auch das zugehörige Netbeans-Projekt heruntergeladen werden:

Dateiname

Zoohandlung.zip

Größe in Bytes

18396

Einfügezeitpunkt

12.1.2018, 22:38:52

Zurück zur Einführung zu Klassen und Objekten

<<tags_@,Zurück zur Einführung zu Klassen und Objekten>>