Deklaration nicht-statischer Methoden in Java
Für die Deklaration von nicht-statischen Methoden einer Klasse gilt alles zuvor für die Deklaration von statischen Methoden Gesagte, abgesehen von den im folgenden beschriebenen Unterschieden und Erweiterungen.
Die nicht-statischen Einträge einer Klassendeklaration bezeichnen wir hier auch als Objektklasse, da sie zu Einträgen von Objekten der Klasse werden.
Main.java
public final class Main
{/* Beginn der "Objektklasse Main" mit nicht-statischen Einträgen */
/* Beginn der statischen Einträgen */
public static void main( final java.lang.String[] args )
{ final Main object = new Main(); /* Anlegen eines Objekts der "Objektklasse Main" */object.method(); }}
transcript
Main.java:5: error: cannot find symbol
object.method(); }}
^
symbol: method method()
location: variable object of type Main
1 error
Das folgende Beispiel zeigt Deklaration und Aufruf einer nicht-statischen Methode.
Main.java
public final class Main
{/* Beginn der "Objektklasse Main" mit nicht-statischen Einträgen */
public void method(){ java.lang.System.out.println( "method" ); }
/* Beginn der statischen Einträgen */
public static void main( final java.lang.String[] args )
{ final Main object = new Main(); /* Anlegen eines Objekts der "Objektklasse Main" */object.method(); }}
transcript
method
- / Nicht-statische Methoden
- Wandeln Sie in dem folgenden Programm die statische Methode »alpha« unter Beibehaltung ihrer anderen Eigenschaften in eine nicht-statische um und passen Sie auch den Aufruf jener Methode entsprechend an (mit einer möglichst kleine Änderung), so daß das Verhalten des Programms sich nicht verändert.
Main.java
public final class Main
{public static int alpha()
{ return 18; }public static void main( final java.lang.String[] args )
{ java.lang.System.out.println( Main.alpha() ); }}transcript
18
UML
Main.java
public final class Main
{/* Beginn der "Objektklasse Main" mit nicht-statischen Einträgen */
public void p()
{ java.lang.System.out.println( "p" ); }/* Beginn der statischen Einträgen */
public static void main( final java.lang.String[] args )
{ Main o = new Main(); /* Anlegen eines Objekts der "Objektklasse Main" */
o.p(); }}transcript
p
- »o.p()« [UML collaboration diagram ][UML 2.0 communication diagram ]
|
|
|
| |
| |
| | p()
| |
| |
| V
|
|
|
.------------------.
| o |
'------------------'
Der Ausdruck »Main.this«
Jedes Objekt einer Klasse enthält eine Kopie jeder nicht-statischen Methode jener Klasse. Der Ausdruck »Main.this« in der Deklaration einer nicht-statischen Methode der Klasse »Main« steht darin jeweils für das Objekt, in dem jene Kopie der nicht-statischen Methode enthalten ist. Kürzer gesagt:
Der Ausdruck »Main.this« steht für das Objekt der Klasse »Main«, in dem die Methode enthalten ist.
Da eine statische Methode in gar keinem Objekt enthalten ist, kann in einer statischen Methode der Ausdruck »Main.this« nicht verwendet werden.
Bei einem Aufruf »o.p()« einer nicht-statischen Methode »p()« eines Objekts »o« wird das Objekt auch als Zielobjekt bezeichnet. (Dieses Objekt ist der Empfänger der Nachricht »p()«.)
Innerhalb einer nicht-statischen Methode einer Klasse »Main« steht der Referenzbezeichner »Main.this« für das Zielobjekt des gerade ausgeführten Aufrufs. Dieses Objekt hat ja den Typ »Main«. (Bei Klassen mit anderen Namen ist »Main« durch den anderen Namen zu ersetzen.)
»Main.this« ist also das Objekt, welches die Methode enthält, in der es verwendet wird.
In einer statischen Methode kann »Main.this« nicht verwendet werden.
Das Zielobjekt beim Aufruf einer nicht-statische Methode ähnelt einem Argument und »Main.this« ähnelt einem Parameter, der aber nicht extra deklariert werden muß.
Das folgende Beispiel zeigt die Verwendung von »Main.this« mit einer Feldangabe.
Main.java
public final class Main
{/* Beginn der "Objektklasse Main" mit nicht-statischen Einträgen */
public int x;
public void p()
{ java.lang.System.out.println( Main.this.x ); }/* Beginn der statischen Einträgen */
public static void main( final java.lang.String[] args )
{ final Main o1 = new Main(); /* Anlegen eines Objekts der "Objektklasse Main" */
o1.x = 1;final Main o2 = new Main(); /* Anlegen eines Objekts der "Objektklasse Main" */
o2.x = 2;java.lang.System.out.println( o1.x ); o1.p(); /* in der Methode p: Main.this = o1 */
java.lang.System.out.println( o2.x ); o2.p(); /* in der Methode p: Main.this = o2 */
java.lang.System.out.println( o1.x ); o1.p(); /* in der Methode p: Main.this = o1 */ }}transcript
1
1
2
2
1
1
Das folgende Beispiel zeigt die Verwendung von »Main.this« mit einem Methodenaufruf.
Main.java
public final class Main
{/* Beginn der "Objektklasse Main" mit nicht-statischen Einträgen */
public void p(){ java.lang.System.out.println( Main.this.getClass() ); }
/* Beginn der statischen Einträgen */
public static void main( final java.lang.String[] args )
{ final Main o = new Main(); /* Anlegen eines Objekts der "Objektklasse Main" */java.lang.System.out.println( o.getClass() );
o.p(); /* o entspricht Main.this */ }}transcript
class Main
class Main
Zu einer statischen Methoden gibt es kein Zielobjekt. Daher kann das Schlüsselwort »this« in einer statischen Methode auch nicht direkt verwendet werden. Jedoch kann es einer statischen Methode als Argument übergeben werden. Das folgende Programmbeispiel zeigt »Main.this« als Angabe des Zielobjekts (ohne den nachgestellten Punkt der voranstehenden Beispiele).
Main.java
public final class Main
{/* Beginn der "Objektklasse Main" mit nicht-statischen Einträgen */
public void p(){ printClass( Main.this ); }
/* Beginn der statischen Einträgen */
public static void printClass( final Main object )
{ java.lang.System.out.println( object.getClass() ); }public static void main( final java.lang.String[] args )
{ final Main o = new Main(); /* Anlegen eines Objekts der "Objektklasse Main" */java.lang.System.out.println( o.getClass() );
o.p(); /* o = Main.this in p und object in printClass */ }}transcript
class Main
class Main
Abkürzungen
Falls keine Mißverständnisse möglich sind, so kann der Name der Klasse vor »this« entfallen. (Wir werden erst später Fälle kennenlernen, in denen die Verwendung des Namens der Klasse nötig ist.)
So wird aus »Main.this.x« (JLS : “qualified this ”) einfach »this.x« und aus »Main.this.getClass()« wird »this.getClass()«.
Tatsächlich werden erst später Beispiele gezeigt werden, in denen die Angabe der Klasse vor »this« nötig ist.
Falls keine Mißverständnisse möglich sind, so kann auch das Schlüsselwort »this« entfallen.
So wird aus »this.x« einfach »x« und aus »this.getClass()« wird »getClass()«.
Wir nennen einen Aufruf, der kein »this.« (zwei vollständige lexikalische Einheiten) vor seiner runden Klammer enthält, einen impliziten Aufruf und einen Aufruf, der kein impliziter Aufruf ist, einen expliziten Aufruf.
Main.java
public final class Main
{/* Beginn der "Objektklasse Main" mit nicht-statischen Einträgen */
public int x;
public void qualifiedThis()
{ java.lang.System.out.println( Main.this.getClass() );
java.lang.System.out.println( Main.this.x );
java.lang.System.out.println( Main.this ); }public void unqualifiedThis()
{ java.lang.System.out.println( this.getClass() );
java.lang.System.out.println( this.x );
java.lang.System.out.println( this ); }public void implicit()
{ java.lang.System.out.println( getClass() );
java.lang.System.out.println( x ); }public void accept( final int x )
{ this.x = x; }/* Beginn der statischen Einträgen */
public static void main( final java.lang.String[] args )
{ final Main o = new Main(); /* Anlegen eines Objekts der "Objektklasse Main" */
o.accept( 5 );
o.qualifiedThis();
o.unqualifiedThis();
o.implicit(); }}transcript
class Main
5
Main@15db9742
class Main
5
Main@15db9742
class Main
5
Methodendeklarationen als Kontexte von Verbaufrufen
Auch eine Methodendeklaration wird manchmal als Kontext eines Verbaufrufs angesehen. Eine statische Methode kann als Kontext eines Verbaufrufs einer statischen Methode, eine nicht-statische Methode als Kontext eines Verbaufrufs einer statischen oder einer nicht-statischen Methode verwendet werden.
Main.java
public final class Main
{public static void statischeMethode()
{ }public void nichtstatischeMethode()
{ }public static void statischeDeklaration()
{ statischeMethode();
/* geht hier nicht: nichtstatischeMethode(); */ }public void nichtstatischeDeklaration()
{ statischeMethode();
nichtstatischeMethode(); }public static void main( final java.lang.String[] args )
{ }}- Protokoll
- (keine Fehlermeldung)
Wenn oben »nichtstatischeMethode()« in der Deklaration von »nichtstatischeDeklaration()« aufgerufen wird, dann ist der Wert von »this« während der Ausführung des Rumpfes von »nichtstatischeMethode()« genau so wie an der Stelle des Aufrufs.
Main.java
public final class Main
{java.lang.String name;
public void nichtstatischeMethode()
{ java.lang.System.out.println( this.name ); }public void nichtstatischeDeklaration()
{ java.lang.System.out.println( this.name );
nichtstatischeMethode(); }public static void main( final java.lang.String[] args )
{ final Main main = new Main();
main.name = "alpha";
main.nichtstatischeDeklaration(); }}- Protokoll
alpha
alpha
Was ist ein Objekt? (Wiederaufnahme)
Ein Objekt ist ein Verzeichnis, das Variablen und Methoden enthält.
Ein Objekt hat eine Speicheraddresse, welche auch „Referenz“ oder „Identität des Objekts“ genannt wird. Diese kann mit anderen Referenzen verglichen oder als Wert verwendet werden, man kann sie jedoch nicht als Text ausgegeben.
Der Wert eines Ausdrucks kann ein Objekt sein; in diesem Sinne werden Objekte im Quelltext durch Ausdrücke angegeben,
Ein Objekt hat eine Klasse (.getClass()). Die Klasse bestimmt, welche Felder das Objekt hat und welche Nachrichten es verarbeiten kann. Die Klasse eines Objekts kann nicht verändert werden. Da die Klasse des Objekts bestimmt, welche Felder und welche Methode es enthält, ist es auch nicht möglich, etwas an den Feldern und Methoden eines Objekts zu verändern (abgesehen von den Werten in denjenigen Feldern des Objekts, welche nicht mit »final« deklariert wurden).
Ein Objekt ist ein System mit einem Zustand. Der Zustand ist bestimmt durch die Werte in den Feldern des Objekts. (Auch eine Variable ist ein System mit einem Zustand, aber der Typ eines Objekts ist immer eine Klasse und das Objekt kann diverse Methoden enthalten, während eine Variable höchstens zwei Operationen unterstützt: Das Abfragen und das Ändern ihres Wertes.)
Ein Objekt hat keinen Namen (Referenzen auf ein Objekt können aber in benannten Variablen gespeichert werden).
Ein Objekt hat eine Lebensdauer: Es existiert nur während das Programm läuft, in dem es vorkommt. Manche Objekte (wie »java.lang.System.out« oder »"abc"«) existieren dabei schon beim Start des Programms, andere können mit »new« während des Programmablaufs erzeugt werden.
Ein Objekt kann bestimmte Nachrichten verarbeiten (z.B. kann »java.lang.System.out« die Nachricht »println()« verarbeiten oder »"abc"« die Nachricht »length()«). Dafür enthält es bestimmte Methoden.
Ein Objekt ist eine Art von simulierter Maschine. Allerdings arbeitet es normalerweise nur, wenn man ihm gerade eine Nachricht geschickt hat, sonst ruht es. Der Zustand des Objekts bleibt aber zwischen verschiedenen Nachrichtenverarbeitungen erhalten. Dies ist ein wichtiger Unterschied zu einer Methode, welche die Inhalte aller ihrer lokalen Variablen am Ende ihrer Aktivität verliert.
Eine Methode kann wie ein Objekt aktiv werden, aber sie vergißt die Werte in ihren lokalen Variablen immer wieder, während ein Objekt diese über einen Aufruf hinaus behalten kann.
Objekte und Klassen
Die nicht-statischen Felder und die nicht-statischen Methoden einer Klasse werden Bestandteile jedes Objekts jener Klasse.
Die statischen Felder und die statischen Methoden einer Klasse werden nicht Bestandteil eines Objekts jener Klasse.
Übungsfragen
? Übungsfrage
- ? Übungsfrage
- Sagen Sie die Ausgabe des folgenden Programms voraus, ohne das Programm zu starten.
Main.java
public final class Main
{/* Beginn der "Objektklasse Main" mit nicht-statischen Einträgen */
public int x;
public void m(){ java.lang.System.out.println( Main.this.x ); }/* Beginn der statischen Einträgen */
public static void main( final java.lang.String[] args )
{ final Main p = new Main(); /* Anlegen eines Objekts der "Objektklasse Main" */
final Main q = new Main(); /* Anlegen eines Objekts der "Objektklasse Main" */
p.x = 8;
q.x = 3;p.m();
q.m();
p.m(); }}
? Ziel- und Argument
Wie heißt das Ziel (Zielobjekt) des folgenden Aufrufs?
Wie heißt das Argument des folgenden Aufrufs?
(Hierbei soll angenommen werden, daß »gamma« und »delta« Namen von Variablen sind, die Objekte enthalten.)
- Aufruf
gamma.m( delta );
? Übungsfrage
- ? Übungsfrage
- Sagen Sie die Ausgabe des folgenden Programms voraus, ohne das Programm zu starten.
Main.java
public final class Main
{/* Beginn der "Objektklasse Main" mit nicht-statischen Einträgen */
int x;
public void m( final Main other )
{ java.lang.System.out.println( this.x - other.x ); }/* Beginn der statischen Einträgen */
public static void main( final java.lang.String[] args )
{ final Main p = new Main(); /* Anlegen eines Objekts der "Objektklasse Main" */
final Main q = new Main(); /* Anlegen eines Objekts der "Objektklasse Main" */
p.x = 9;
q.x = 5;p.m( q );
q.m( p ); }}
? Übungsfrage
- ? Übungsfrage
- Sagen Sie die Ausgabe des folgenden Programms voraus, ohne das Programm zu starten.
Main.java
public final class Main
{/* Beginn der "Objektklasse Main" mit nicht-statischen Einträgen */
public int x;
public void m(){ java.lang.System.out.println( Main.this.x++ ); }
/* Beginn der statischen Einträgen */
public static void main( final java.lang.String[] args )
{ final Main p = new Main(); /* Anlegen eines Objekts der "Objektklasse Main" */
final Main q = new Main(); /* Anlegen eines Objekts der "Objektklasse Main" */
p.x = 8;
q.x = 3;p.m();
q.m();
p.m(); }}
? Übungsfrage
- ? Übungsfrage (mittelschwierig)
- Sagen Sie die Ausgabe des folgenden Programms voraus, ohne das Programm zu starten.
Main.java
public final class Main
{/* Beginn der "Objektklasse Main" mit nicht-statischen Einträgen */
public int x;
public int a(){ return 14; }
public int b(){ return Main.this.x; }
public void m( final Main other )
{ java.lang.System.out.println( Main.this.a() - other.b() ); }/* Beginn der statischen Einträgen */
public static void main( final java.lang.String[] args )
{ final Main p = new Main(); /* Anlegen eines Objekts der "Objektklasse Main" */
final Main q = new Main(); /* Anlegen eines Objekts der "Objektklasse Main" */
p.x = 9;
q.x = 5;p.m( q );
q.m( p ); }}
Übungsaufgaben
/ Übungsaufgabe 0
Ergänzen Sie in dem untenstehenden Programm benötigte Deklarationen von Methoden und von Feldern, so daß man mit »hello()« den Text »Hallo, Welt« ausgeben kann, wie in dem untenstehenden Programm zu sehen ist. Dabei können die beiden Ellipsen »…« durch andere Texte ersetzt werden. Das Hauptprogramm darf nicht verändert werden.
Main.java
public final class Main
{/* Beginn der "Objektklasse Main" mit nicht-statischen Einträgen */
…
/* Beginn der statischen Einträgen */
…
public static void main( final java.lang.String[] args )
{ final Main o = new Main(); /* Anlegen eines Objekts der "Objektklasse Main" */
final Main x = new Main(); /* Anlegen eines Objekts der "Objektklasse Main" */
o.hello();
x.hello(); }}java.lang.System.out
Hallo, Welt
Hallo, Welt
/ Übungsaufgabe 1
Ergänzen Sie in dem untenstehenden Programm benötigte Deklarationen von Methoden und von Feldern, so daß man mit »hello(java.lang.String)« eine Person begrüßen kann, wie in dem untenstehenden Programm zu sehen ist.
Main.java
public final class Main
{/* Beginn der "Objektklasse Main" mit nicht-statischen Einträgen */
…
/* Beginn der statischen Einträgen */
…
public static void main( final java.lang.String[] args )
{ final Main o = new Main(); /* Anlegen eines Objekts der "Objektklasse Main" */
final Main x = new Main(); /* Anlegen eines Objekts der "Objektklasse Main" */
o.hello( "Mia" );
x.hello( "Ben" ); }}java.lang.System.out
Hallo Mia
Hallo Ben
/ Übungsaufgabe 2
- / = Getter
- Deklarieren Sie in dem folgenden Programm an der Stelle der Lücke »…« eine nicht-statische Methode »getX()«, welche den Wert des Feldes »x« zurückgibt!
- (Die anderen Zeilen sollten nicht verändert werden.)
Main.java
public final class Main
{/* Beginn der "Objektklasse Main" mit nicht-statischen Einträgen */
public int x;
…
/* Beginn der statischen Einträgen */
public static void main( final java.lang.String[] args )
{ { final Main main = new Main(); /* Anlegen eines Objekts der "Objektklasse Main" */
main.x = 12; java.lang.System.out.println( main.getX() ); }
{ final Main main = new Main(); /* Anlegen eines Objekts der "Objektklasse Main" */
main.x = 17; java.lang.System.out.println( main.getX() ); }}}java.lang.System.out
12
17
/ Übungsaufgabe 3
- / = Setter
- Deklarieren Sie in dem folgenden Programm an der Stelle der Lücke »…« eine nicht-statische Methode »setX(int)«, welche den Wert des Feldes »x« als Wert des Arguments des Aufrufs von »setX(int)« festlegt!
- (Die anderen Zeilen sollten nicht verändert werden.)
Main.java
public final class Main
{/* Beginn der "Objektklasse Main" mit nicht-statischen Einträgen */
public int x;
…/* Beginn der statischen Einträgen */
public static void main( final java.lang.String[] args )
{ final Main main = new Main(); /* Anlegen eines Objekts der "Objektklasse Main" */
main.setX( 33 ); java.lang.System.out.println( main.x );
main.setX( 74 ); java.lang.System.out.println( main.x ); }}java.lang.System.out
33
74
/ Übungsaufgabe 4
Ergänzen Sie in dem untenstehenden Programm benötigte Deklarationen von Methoden und von Feldern, so daß man mit »set« einen Namen für ein Objekt festlegen kann, das dann von der statischen Methode »hello(Main)« verwendet wird, um eine entsprechende Begrüßung auszugeben, wie in dem untenstehenden Programm zu sehen ist.
(Objekte haben in Java im allgemeinen ja keinen Namen. Ein Objekt kann aber eine Variable enthalten, die einen Namen enthält.)
Main.java
public final class Main
{/* Beginn der "Objektklasse Main" mit nicht-statischen Einträgen */
…
/* Beginn der statischen Einträgen */
…
public static void main( final java.lang.String[] args )
{ final Main o = new Main(); /* Anlegen eines Objekts der "Objektklasse Main" */
final Main x = new Main(); /* Anlegen eines Objekts der "Objektklasse Main" */
o.set( "Pia" );
x.set( "Leo" );
hello( o );
hello( x );
o.set( "Zoe" );
hello( o ); }}java.lang.System.out
Hallo Pia
Hallo Leo
Hallo Zoe
/ Übungsaufgabe 5
Erstellen Sie eine Erzeugungsmethode »makeMain()«, die ein neues Objekt der Klasse »Main« zurückgibt.
Main.java
public final class Main
{/* Beginn der "Objektklasse Main" mit nicht-statischen Einträgen */
…
/* Beginn der statischen Einträgen */
…
public static void main( final java.lang.String[] args )
{ final Main o = makeMain(); /* Anlegen eines Objekts der "Objektklasse Main" */
final Main x = makeMain(); /* Anlegen eines Objekts der "Objektklasse Main" */
java.lang.System.out.println( o );
java.lang.System.out.println( x ); }}transcript
Main@15db9742
Main@6d06d69c
/ Übungsaufgabe 6
Erstellen Sie eine Erzeugungsmethode »makeMain(int)«, die ein neues Objekt der Klasse »Main« zurückgibt, welches den beim Aufruf der Erzeugungsmethode angegebenen Wert enthält, und eine »get«-Methode, die jenen im Objekte enthaltenen Wert zurückgibt.
Main.java
public final class Main
{/* Beginn der "Objektklasse Main" mit nicht-statischen Einträgen */
…
/* Beginn der statischen Einträgen */
…
public static void main( final java.lang.String[] args )
{ final Main o = makeMain( 2 ); /* Anlegen eines Objekts der "Objektklasse Main" */
final Main x = makeMain( 3 ); /* Anlegen eines Objekts der "Objektklasse Main" */
java.lang.System.out.println( o.get() );
java.lang.System.out.println( x.get() ); }}java.lang.System.out
2
3
/ Übungsaufgabe 7
Ergänzen Sie in dem untenstehenden Programm benötigte Deklarationen von Methoden und von Feldern, so daß man mit »hello()« eine Person begrüßen kann, die vorher mit »set« festgelegt wurde, wie in dem untenstehenden Programm zu sehen ist.
Main.java
public final class Main
{/* Beginn der "Objektklasse Main" mit nicht-statischen Einträgen */
…
/* Beginn der statischen Einträgen */
…
public static void main( final java.lang.String[] args )
{ final Main o = new Main(); /* Anlegen eines Objekts der "Objektklasse Main" */
final Main x = new Main(); /* Anlegen eines Objekts der "Objektklasse Main" */
o.set( "Lea" );
x.set( "Alf" );
x.hello();
x.hello();
o.hello();
o.set( "Tim" );
o.hello(); }}java.lang.System.out
Hallo Alf
Hallo Alf
Hallo Lea
Hallo Tim
/ Übungsaufgabe 8
- / = Adder
- Deklarieren Sie in dem folgenden Programm an der Lücke »…« eine nicht-statische Methode »addToX(int)«, welche den Wert des Arguments ihres Aufrufs zum Werte des Feldes »x« hinzuaddiert (so daß der Wert jenes Feldes entsprechend erhöht wird, sich also verändert)!
- (Die anderen Zeilen sollten nicht verändert werden.)
Main.java
public final class Main
{/* Beginn der "Objektklasse Main" mit nicht-statischen Einträgen */
public int x;
…/* Beginn der statischen Einträgen */
public static void main( final java.lang.String[] args )
{ final Main main = new Main(); /* Anlegen eines Objekts der "Objektklasse Main" */
main.x = 10;
main.addToX( 12 );
java.lang.System.out.println( main.x );
main.addToX( 17 );
java.lang.System.out.println( main.x ); }}java.lang.System.out
22
39
/ Übungsaufgabe 9 _
- / = Adder
- Deklarieren Sie in dem folgenden Programm an der Lücke »…« eine statische Methode »void addToX(Main,int)«, welche den Wert des zweiten Arguments ihres Aufrufs zum Werte des Feldes »x« des ersten Arguments hinzuaddiert!
- (Die anderen Zeilen sollten nicht verändert werden.)
Main.java
public final class Main
{/* Beginn der "Objektklasse Main" mit nicht-statischen Einträgen */
public int x;
…/* Beginn der statischen Einträgen */
…
public static void main( final java.lang.String[] args )
{ final Main main = new Main(); /* Anlegen eines Objekts der "Objektklasse Main" */
main.x = 10;
addToX( main, 12 );
java.lang.System.out.println( main.x );
addToX( main, 17 );
java.lang.System.out.println( main.x ); }}java.lang.System.out
22
39
/ Übungsaufgabe 10 ⃗
- / = Adder
- Deklarieren Sie in dem folgenden Programm eine statische Methode »Main addToX(Main,int)«, welche ein neues Objekt der Klasse »Main« ergibt, bei dem der Wert des Feldes »x« die Summe aus dem Wert des Feldes »x« des ersten Arguments und dem zweiten Argument ist.
- (Die anderen Zeilen sollten nicht verändert werden.)
Main.java
public final class Main
{/* Beginn der "Objektklasse Main" mit nicht-statischen Einträgen */
public int x;
/* Beginn der statischen Einträgen */
…
public static void main( final java.lang.String[] args )
{ Main main = new Main(); /* Anlegen eines Objekts der "Objektklasse Main" */
main.x = 10;
main = addToX( main, 12 );
java.lang.System.out.println( main.x );
main = addToX( main, 17 );
java.lang.System.out.println( main.x ); }}java.lang.System.out
22
39
/ Übungsaufgabe 11 ⃗
- / = Adder
- Deklarieren Sie in dem folgenden Programm an der Lücke »…« eine nicht-statische Methode »Main addToX(int)«, welche ein neues Objekt der Klasse »Main« ergibt, bei dem der Wert des Feldes »x« die Summe aus dem Wert des Feldes »x« ihres Objekts und dem Wert des beim Aufruf angegebenen Arguments ist.
- (Die anderen Zeilen sollten nicht verändert werden.)
Main.java
public final class Main
{/* Beginn der "Objektklasse Main" mit nicht-statischen Einträgen */
public int x;
…/* Beginn der statischen Einträgen */
public static void main( final java.lang.String[] args )
{ Main main = new Main(); /* Anlegen eines Objekts der "Objektklasse Main" */
main.x = 10;
main = main.addToX( 12 );
java.lang.System.out.println( main.x );
main = main.addToX( 17 );
java.lang.System.out.println( main.x ); }}java.lang.System.out
22
39
/ Übungsaufgabe 12 ⃖
Ergänzen Sie in dem untenstehenden Programm an der Stelle der Ellipse »…« benötigte Deklarationen von Methoden und von Feldern, so daß man mit »greet(java.lang.String)« eine Person begrüßen kann, wobei die Begrüßungsformel vorher mit »set« festgelegt wurde, wie in dem untenstehenden Programm zu sehen ist.
Main.java
public final class Main
{/* Beginn der "Objektklasse Main" mit nicht-statischen Einträgen */
…
/* Beginn der statischen Einträgen */
public static void main( final java.lang.String[] args )
{ final Main o = new Main(); /* Anlegen eines Objekts der "Objektklasse Main" */
final Main x = new Main(); /* Anlegen eines Objekts der "Objektklasse Main" */
o.set( "Hallo" );
x.set( "Guten Tag," );
o.greet( "Max" );
o.greet( "Lea" );
x.greet( "Max" );
x.greet( "Lea" );
x.set( "Willkommen" );
o.greet( "Max" );
o.greet( "Lea" );
x.greet( "Max" );
x.greet( "Lea" ); }}java.lang.System.out
Hallo Max
Hallo Lea
Guten Tag, Max
Guten Tag, Lea
Hallo Max
Hallo Lea
Willkommen Max
Willkommen Lea
/ Übungsaufgabe 13 ⃗
Ergänzen Sie in dem untenstehenden Programm benötigte Deklarationen von Methoden und von Feldern, so daß man mit »set« den Wert des Zielobjekts festlegen kann, und mit »sum« die Summe zweier Objekte ermittelt wird.
Main.java
public final class Main
{/* Beginn der "Objektklasse Main" mit nicht-statischen Einträgen */
…
/* Beginn der statischen Einträgen */
…
public static void main( final java.lang.String[] args )
{ final Main o = new Main(); /* Anlegen eines Objekts der "Objektklasse Main" */
final Main x = new Main(); /* Anlegen eines Objekts der "Objektklasse Main" */
o.set( 4 );
x.set( 3 );
java.lang.System.out.println( sum( o, x )); }}java.lang.System.out
7
/ Übungsaufgabe 14 ⃗
Ergänzen Sie in dem untenstehenden Programm an der Stelle der Ellipse »…« benötigte Methodendeklarationen und Felder, so daß man mit »set« den Wert des Zielobjekts festlegen kann, und mit »add« das Argumentobjekt zum Zielobjekt addiert wird. Die Methode »get()« soll dann den Wert des Objektes liefern.
Main.java
public final class Main
{/* Beginn der "Objektklasse Main" mit nicht-statischen Einträgen */
…
/* Beginn der statischen Einträgen */
public static void main( final java.lang.String[] args )
{ final Main o = new Main(); /* Anlegen eines Objekts der "Objektklasse Main" */
final Main x = new Main(); /* Anlegen eines Objekts der "Objektklasse Main" */
o.set( 4 );
x.set( 3 );
o.add( x );
o.add( x );
java.lang.System.out.println( o.get() ); }}java.lang.System.out
10
/ Übungsaufgabe 15 ⃗
Ergänzen Sie in dem untenstehenden Programm an der Stelle der Ellipse »…« benötigte Methodendeklarationen und Felder, so daß man mit »set« den Wert des Zielobjekts festlegen kann, und mit »plus« eine neues Objekt erzeugt wird, welches die Summe des Zielobjekts und des Argumentwertes enthält. Die Methode »get()« soll dann den Wert des Objektes liefern.
Main.java
public final class Main
{/* Beginn der "Objektklasse Main" mit nicht-statischen Einträgen */
…
/* Beginn der statischen Einträgen */
public static void main( final java.lang.String[] args )
{ final Main o = new Main(); /* Anlegen eines Objekts der "Objektklasse Main" */
final Main x = new Main(); /* Anlegen eines Objekts der "Objektklasse Main" */
o.set( 4 );
java.lang.System.out.println( o.plus( 3 ).get() ); }}java.lang.System.out
10
/ Übungsaufgabe 16
Ergänzen Sie in dem untenstehenden Programm an der Stelle der Ellipse »…« benötigte Methodendeklarationen und Felder, so daß man mit »setName« einen Namen und mit »setGreeting« eine Begrüßungsformel festlegen kann, die dann von der nicht-statischen Methode »greet« verwendet werden, um eine entsprechende Begrüßung auszugeben, wie in dem untenstehenden Programm zu sehen ist.
Main.java
public final class Main
{/* Beginn der "Objektklasse Main" mit nicht-statischen Einträgen */
…
/* Beginn der statischen Einträgen */
public static void main( final java.lang.String[] args )
{ final Main o = new Main(); /* Anlegen eines Objekts der "Objektklasse Main" */
o.setName( "Pia" );
o.setGreeting( "Guten Morgen," );
o.greet();
o.setName( "Ben" );
o.greet(); }}java.lang.System.out
Guten Morgen, Pia!
Guten Morgen, Ben!
/ Übungsaufgabe 17 ⃗
Ergänzen Sie in dem untenstehenden Programm an der Stelle der Ellipse »…« benötigte Methodendeklarationen und Felder, so daß man mit »set« zwei Werte des Zielobjekts festlegen kann, die mit »print« ausgegeben werden können, wie in dem untenstehenden Programm zu sehen ist.
Main.java
public final class Main
{/* Beginn der "Objektklasse Main" mit nicht-statischen Einträgen */
…
/* Beginn der statischen Einträgen */
public static void main( final java.lang.String[] args )
{ final Main o = new Main(); /* Anlegen eines Objekts der "Objektklasse Main" */
final Main x = new Main(); /* Anlegen eines Objekts der "Objektklasse Main" */
o.set( 2, 3 );
x.set( 5, 7 );
o.print();
o.print();
x.print();
o.set( 7, 1 );
o.print();
x.print(); }}java.lang.System.out
2, 3
2, 3
5, 7
7, 1
5, 7
/ Übungsaufgabe 18 ⃗
- / + Kapselung
- Kombinieren Sie Methodendeklarationen vorheriger Aufgaben zu »getX()«, »setX(int)« und »addToX(int)«, so, daß die folgende main -Methode wie gezeigt läuft!
Main.java
public final class Main
{/* Beginn der "Objektklasse Main" mit nicht-statischen Einträgen */
public int x;
…/* Beginn der statischen Einträgen */
public static void main( final java.lang.String[] args )
{ final Main main = new Main(); /* Anlegen eines Objekts der "Objektklasse Main" */
main.setX( 10 );
main.addToX( 12 );
main.addToX( 17 );
java.lang.System.out.println( main.getX() ); }}java.lang.System.out
39
/ Übungsaufgabe 19 ⃗
+ (Erst Nachbesprechung der vorigen Aufgabe!) Deklarieren Sie eine Methode »value« für Objekte, welche die Summe von Werte zurückgibt, zuvor beim Aufruf der Methode »add« desselben Objekts übergeben wurden.
Main.java
public final class Main
{/* Beginn der "Objektklasse Main" mit nicht-statischen Einträgen */
…
/* Beginn der statischen Einträgen */
public static void main( final java.lang.String[] args )
{ final Main summierer = new Main(); /* Anlegen eines Objekts der "Objektklasse Main" */
summierer.add( 9 ); summierer.add( 14 );
java.lang.System.out.println( summierer.value() ); }}java.lang.System.out
23
Main.java
public final class Main
{/* Beginn der "Objektklasse Main" mit nicht-statischen Einträgen */
public int x;
…/* Beginn der statischen Einträgen */
…
public static void main( final java.lang.String[] args )
{ final Main summierer = new Main(); /* Anlegen eines Objekts der "Objektklasse Main" */
summierer.add( 9 ); summierer.add( 14 );
java.lang.System.out.println( summierer.value() );
final Main summierer1 = new Main(); /* Anlegen eines Objekts der "Objektklasse Main" */
summierer1.add( 12 ); summierer1.add( 7 );
java.lang.System.out.println( summierer1.value() ); }}java.lang.System.out
23
19
/ Übungsaufgabe 20
Ergänzen Sie in dem untenstehenden Programm an der Stelle der Ellipse »…« benötigte Methodendeklarationen und Felder, so daß man mit »set« zwei Werte des Zielobjekts festlegen kann, und mit »asString« eine Darstellung des Objektes als Text erhält, wie in dem untenstehenden Programm zu sehen ist.
Main.java
public final class Main
{/* Beginn der "Objektklasse Main" mit nicht-statischen Einträgen */
public int x;
…/* Beginn der statischen Einträgen */
public static void main( final java.lang.String[] args )
{ final Main o = new Main(); /* Anlegen eines Objekts der "Objektklasse Main" */
final Main x = new Main(); /* Anlegen eines Objekts der "Objektklasse Main" */
o.set( 3, 4 );
x.set( 3, 1 );
java.lang.System.out.println( o.asString() );
java.lang.System.out.println( x.asString() ); }}java.lang.System.out
Main[ 3, 4 ]
Main[ 3, 1 ]
/ Übungsaufgabe 21 _
- / + Setter 1
- Überarbeiten Sie die folgende Deklaration der Klasse »Main« so, daß die dann parameterlose nicht-statische Methode »average()« den Mittelwert der beiden Variablen eines Objektes ergibt. die zuvor mit den nicht-statischen Methoden »setX(int)« und »setY(int)« auf bestimmte Werte gesetzt wurden.
Main.java
public final class Main
{/* Beginn der "Objektklasse Main" mit nicht-statischen Einträgen */
public int average( final int x, final int y )
{ return ( x + y )/ 2; }/* Beginn der statischen Einträgen */
public static void main( final java.lang.String[] args )
{ java.lang.System.out.println( new Main().average( 2, 4 )); }}java.lang.System.out
3
Main.java
public final class Main
{/* Beginn der "Objektklasse Main" mit nicht-statischen Einträgen */
…
/* Beginn der statischen Einträgen */
public static void main( final java.lang.String[] args )
{ final Main main = new Main(); /* Anlegen eines Objekts der "Objektklasse Main" */
main.setX( 2 );
main.setY( 8 );
java.lang.System.out.println( main.average() ); }}java.lang.System.out
5
/ Übungsaufgabe 22 ⃗
Ergänzen Sie in dem untenstehenden Programm an der Stelle der Ellipse »…« benötigte Methodendeklarationen und Felder, so daß man mit »set« zwei Werte des Zielobjekts festlegen kann, und mit »sum« und »dif« deren Summe beziehungsweise Differenz erhält, wie in dem untenstehenden Programm zu sehen ist.
Main.java
public final class Main
{/* Beginn der "Objektklasse Main" mit nicht-statischen Einträgen */
…
/* Beginn der statischen Einträgen */
public static void main( final java.lang.String[] args )
{ final Main o = new Main(); /* Anlegen eines Objekts der "Objektklasse Main" */
o.set( 4, 1 );
java.lang.System.out.println( o.sum() );
java.lang.System.out.println( o.dif() );
o.set( 7, 2 );
java.lang.System.out.println( o.dif() );
java.lang.System.out.println( o.sum() ); }}java.lang.System.out
5
3
5
9
/ Übungsaufgabe 23 *
Fügen Sie noch eine Methode »setSumDif« hinzu, mit der man die Summe und die Differenz der beiden Felder festlegen kann.
Main.java
public final class Main
{/* Beginn der "Objektklasse Main" mit nicht-statischen Einträgen */
…
/* Beginn der statischen Einträgen */
public static void main( final java.lang.String[] args )
{ final Main o = new Main(); /* Anlegen eines Objekts der "Objektklasse Main" */
o.set( 4, 1 );
java.lang.System.out.println( o.sum() );
java.lang.System.out.println( o.dif() );
o.set( 7, 2 );
java.lang.System.out.println( o.dif() );
java.lang.System.out.println( o.sum() );
o.setSumDif( 7, 2 );
java.lang.System.out.println( o.dif() );
java.lang.System.out.println( o.sum() );
}}java.lang.System.out
5
3
5
9
7
2
/ Übungsaufgabe 24 ⃖
Ergänzen Sie in dem untenstehenden Programm an der Stelle der Ellipse »…« benötigte Methodendeklarationen und Felder, so daß man mit »set« zwei Werte des Zielobjekts festlegen kann, und mit »add« die Werte eines anderen Objektes zum Zielobjekt addieren kann, wie in dem untenstehenden Programm zu sehen ist.
Unter dem „Addieren eines Objektes zu einem anderen Objekt“ verstehen wir hier das feldweise Addieren, das heißt: jedes Feld des zweiten Objektes wird zu dem gleichnamigen Feld des ersten Objektes hinzuaddiert. Unter dem „Hinzuaddieren eines Feldes zu einem Felde“ verstehen wir hier, daß die Summe der bisherigen Werte der beiden Felder in das zweiten Feld geschrieben wird. Man kann sich auch die unten gezeigte Beispielausgabe ansehen, um das Gemeinte zu verstehen.
a b
.----.----. .----.----.
vorher | 3 | 4 | | 3 | 1 |
'----'----' '----'----'
| | /| /|
| | / | / |
| | / | / |
| | / |/ |
| | / | |
a.add( b ) | | / /| |
| |/ / | |
| / / | |
| /| / | |
| / | / | |
| / | / | |
|/ |/ | |
+ + | |
.----.----. .----.----.
nachher | 6 | 5 | | 3 | 1 |
'----'----' '----'----'Main.java
public final class Main
{/* Beginn der "Objektklasse Main" mit nicht-statischen Einträgen */
…
/* Beginn der statischen Einträgen */
public static void main( final java.lang.String[] args )
{ final Main a = new Main(); /* Anlegen eines Objekts der "Objektklasse Main" */
final Main b = new Main(); /* Anlegen eines Objekts der "Objektklasse Main" */
a.set( 3, 4 );
b.set( 3, 1 );
a.add( b );
java.lang.System.out.println( a.x );
java.lang.System.out.println( a.y );
java.lang.System.out.println( b.x );
java.lang.System.out.println( b.y ); }}java.lang.System.out
6
5
3
1
/ Übungsaufgabe 25 ⃖
Hinweis für den Dozenten ► Diese Aufgabe kann mit den bisher vermittelten Kenntnissen gelöst werden.
+ Deklarieren Sie eine Methode »value()« für Objekte, die zählen, wie oft ihre Methode »count()« zuvor aufgerufen wurde.
Main.java
public final class Main
{/* Beginn der "Objektklasse Main" mit nicht-statischen Einträgen */
…
/* Beginn der statischen Einträgen */
public static void main( final java.lang.String[] args )
{ final Main counter0 = new Main(); /* Anlegen eines Objekts der "Objektklasse Main" */
final Main counter1 = new Main(); /* Anlegen eines Objekts der "Objektklasse Main" */
counter1.count(); counter1.count(); counter1.count();
counter1.count(); counter1.count();
java.lang.System.out.println( counter0.value() );
java.lang.System.out.println( counter1.value() ); }}java.lang.System.out
0
5
/ Übungsaufgabe 26 ←
- / = Aufrufe von Methoden eines Parameters (callback I)
- Schreiben Sie eine Klasse »Main« mit einer nicht-statischen Methode mit dem Deskriptor »void run()« welche das Wort »run« ausgibt.
(Der Deskriptor einer Methode ist die Kombination aus dem Aufruftyp dieser Methode und der Signatur dieser Methode. Die Signatur einer Methode ist die Kombination aus dem Methodenbezeichner dieser Methode und der eingeklammerten Parameterliste dieser Methode.) - Schreiben Sie dann eine statische Methode »executeTwice«, die ein Objekt der Klasse »Main« als Argument akzeptiert und dann die Methode »run« dieses Objekts zweimal hintereinander aufruft.
- Erzeugen Sie dann im Hauptprogramm (in der main -Methode) ein Exemplar der Klasse »Main« und übergeben Sie es an die Methode »executeTwice«.
Hinweis: Bei dieser Übungsaufgabe kann die Lösung schrittweise erarbeitet werden, indem man jeden Satz der Aufgabenstellung einzeln abarbeitet.
/ Übungsaufgabe 27 ←
- / = Aufrufe von toString() (callback II, Polymorphie)
- Ergänzen Sie die untenstehende Deklaration der Klasse »Main« um eine Deklaration einer nicht-statischen parameterlosen public-Methode »toString«, welche den Rückgabetyp »java.lang.String« hat und als Ergebnis die Zeichenfolge »Main#toString()« liefert. (Diese Methode soll nichts ausgeben. Diese Methode soll nichts anderes tun als beschrieben.)
- Bei jedem Aufruf dieser Methode »toString« soll außerdem ein Feld namens »count« in dem Objekt um 1 hochgezählt werden (int -Felder erhalten beim Anlegen des Objekts automatisch den Wert 0).
Hinweis: Bei dieser Übungsaufgabe kann die Lösung schrittweise erarbeitet werden, indem man jeden Satz der Aufgabenstellung einzeln abarbeitet.
Überlegen Sie sich dann (nachdem Sie das erhaltene Programm gestartet und seine Ausgabe gesehen haben) Antworten auf die folgenden Fragen:
- Wie ist es möglich, daß die Methode »toString()« aufgerufen wird, wenn das Programm gar keinen Aufruf dieser Methode enthält?
- Wie kann »println« eine Methode unserer Klasse »Main« aufrufen, wenn »println« geschrieben wurde, als es unsere Klasse »Main« noch gar nicht gab?
(Die ersten beiden Zeilen und die letzten fünf Zeilen sollten nicht verändert werden.)
Main.java
public final class Main
{/* Beginn der "Objektklasse Main" mit nicht-statischen Einträgen */
…
/* Beginn der statischen Einträgen */
…
public static void main( final java.lang.String[] args )
{ final Main object = new Main(); /* Anlegen eines Objekts der "Objektklasse Main" */
java.lang.System.out.println( object.count );
java.lang.System.out.println( object );
java.lang.System.out.println( object.count ); }}
Normalerweise ruft ein Programm Bibliotheksmethoden auf. Wenn eine Bibliotheksmethode eines Methode des Programms aufruft (oder eine Methode eines an sie übergebenen Objekts), so spricht man auch von einem „Rückruf“ (“call back ”). Genauso spricht man auch von einem Rückruf, wenn man ein Objekt an eine Methode übergibt, und diese dann ihrerseits eine Methode des übergebenen Objekts aufruft.
/ Zusatzaufgabe
Schreiben Sie eine Klasse für Objekte, die einen Punkt in der Ebene repräsentieren und Getter und Setter jeweils sowohl für kartesische Koordinate als auch für Polarkoordinaten haben (also insgesamt vier Getter und vier Setter).
Vorteil der objektorientierten Programmierung
Ein Lemma (eine Signatur, ein Symbol), wie beispielsweise »toString()«, kann für einen Typ erweitert werden, ohne daß bereits vorhandene Typen dazu verändert werden müssen.
In der prozeduralen Programmierung entspräche der Signatur »toString()« eine Prozedur »toString(java.lang.Object)« mit einer Fallunterscheidung nach dem Typ des Objekts. Wenn ein neuer Typ hinzugefügt werden soll, so müßte diese Prozedur überarbeitet werden, was aber oft nicht auf einfache Weise möglich wäre, falls sie sich in einer Bibliothek oder von einem anderen Programmierer stammt befindet.
Daher ist das Hinzufügen neuer Typen in der objektorientierten Programmierung einfacher und weniger fehlerträchtig als in der prozeduralen Programmierung.
Das folgende Programm erweitert die Signatur »toString()« beispielsweise für unsere Klasse »Main«. »java.lang.System.out.println« benutzt nun sofort diese
Main.java
public final class Main
{/* Beginn der "Objektklasse Main" mit nicht-statischen Einträgen */
public java.lang.String toString(){ return "Main"; }
/* Beginn der statischen Einträgen */
public static void main( final java.lang.String[] args )
{ java.lang.System.out.println( new java.lang.Object() );
java.lang.System.out.println( new Main() ); }}transcript
java.lang.Object@15db9742
Main