Objektparameter in Java (Objektparameter in Java), Lektion, Seite 723362
https://www.purl.org/stefan_ram/pub/objektparameter_java (Permalink) ist die kanonische URI dieser Seite.
Stefan Ram

Obertypparameter in Java 

Wir erinnern an folgendes:

Obertypparameter

Durch die Wahl eines geeigneten Parametertyps kann eine Methode Argumente verschiedener Typen, für die sie sinnvoll ist, akzeptieren.

Main.java

public final class Main
{

public static void m( final java.lang.CharSequence sequence )
{ java.lang.System.out.printf( "%s%n%s%n%s%n%s%n",
sequence.length(),
sequence.charAt( 0 ),
sequence.subSequence( 0, 3 ),
sequence.toString() ); }

public static void main( final java.lang.String[] args )
{ m( new java.lang.String( "Alpha" ));
m( new java.lang.StringBuilder( "Alpha" ));
m( new java.lang.StringBuffer( "Alpha" )); }}

transcript
5
A
Alp
Alpha
5
A
Alp
Alpha
5
A
Alp
Alpha

Würde der Parametertyp unnötig einschränkend gewählt werden, wären sinnvolle Aufrufmöglichkeiten versperrt.

Main.java

public final class Main
{

public static void m( final java.lang.String sequence )
{ java.lang.System.out.printf( "%s%n%s%n%s%n%s%n",
sequence.length(),
sequence.charAt( 0 ),
sequence.subSequence( 0, 3 ),
sequence.toString() ); }

public static void main( final java.lang.String[] args )
{ m( new java.lang.String( "Alpha" ));
m( new java.lang.StringBuilder( "Alpha" ));
m( new java.lang.StringBuffer( "Alpha" )); }}

transcript
Main.java:13: error: incompatible types: StringBuilder cannot be converted to String
m( new java.lang.StringBuilder( "Alpha" ));
^
Main.java:14: error: incompatible types: StringBuffer cannot be converted to String
m( new java.lang.StringBuffer( "Alpha" )); }}
^
Note: Some messages have been simplified; recompile with -Xdiags:verbose to get full output
2 errors

Ein weiteres Beispiel

Die unten verwendeten Nachrichten mit dem Verb »valueOf« ergeben ein Objekt ihrer Zielklasse, welches den Wert darstellt, der durch das Argument der Nachrichten angegeben wird.

Die Methoden namens »printInt« sollen die Antwort eines Objekts auf die Frage »intValue()?« ausgeben.

Main.java

public final class Main
{

public static void printInt( final java.lang.Double p )
{ java.lang.System.out.println( p.intValue() ); }

public static void printInt( final java.lang.Integer p )
{ java.lang.System.out.println( p.intValue() ); }

public static void main( final java.lang.String[] args )
{ printInt( java.lang.Double.valueOf( "2" ));
printInt( java.lang.Integer.valueOf( "2" )); }}

transcript
2
2

Es kann aber zu Problemen führen, wenn ein Programm so viel Redundanz enthält. Im Falle des obigen Programms sind die beiden Deklarationen der Methoden namens »printInt« fast gleich – sie unterscheiden sich nur im Typ des Parameters.

Das folgende Diagramm zeigt, daß der Typ »java.lang.Number« Obertyp von »java.lang.Double« und »java.lang.Integer« ist und eine Signatur »intValue()« enthält.

Typhierarchie
                  .---------------------------.
| java.lang.Object |
|---------------------------|
|---------------------------|
'---------------------------'
^
/_\
|
|
.---------------------------.
| java.lang.Number |
|---------------------------|
|---------------------------|
| + intValue() |
'---------------------------'
^
/_\
|
|
.----------------'----------------.
| |
.---------------------------. .---------------------------.
| java.lang.Double | | java.lang.Integer |
|---------------------------| |---------------------------|
|---------------------------| |---------------------------|
| + intValue() | | + intValue() |
'---------------------------' '---------------------------'

Die statische Klassenmethode »java.lang.Integer.valueOf(java.lang.String)« liefert einen Wert vom Typ »java.lang.Integer«.

Die statische Klassenmethode »java.lang.Double.valueOf(java.lang.String)« liefert einen Wert vom Typ »java.lang.Double«.

Der Typ »java.lang.Number« ist ein gemeinsamer Obertyp von »java.lang.Integer« und »java.lang.Double« und enthält die Methode »intValue()«.

Daher kann im Aufruf einer Methode, die einen Parameter vom Typ »java.lang.Number« hat, sowohl ein Argumentausdruck vom Typ »java.lang.Integer« als auch vom Typ »java.lang.Double« verwendet werden.

Main.java

public final class Main
{

public static void printInt( final java.lang.Number p )
{ java.lang.System.out.println( p.intValue() ); }

public static void main( final java.lang.String[] args )
{ printInt( java.lang.Double.valueOf( "2" ));
printInt( java.lang.Integer.valueOf( "2" )); }}

transcript
2
2

Der Typ »java.lang.Double« wäre zu speziell, so daß ein Argument beim Aufruf von »printInt« nicht akzeptiert werden würde.

Main.java

public final class Main
{

public static void printInt( final java.lang.Double p )
{ java.lang.System.out.println( p.intValue() ); }

public static void main( final java.lang.String[] args )
{ printInt( java.lang.Double.valueOf( "2" ));
printInt( java.lang.Integer.valueOf( "2" )); }}

Protokoll
Main.java:9: error: method printInt in class Main cannot be applied to given types;
printInt( java.lang.Integer.valueOf( "2" )); }}
^
required: Double
found: Integer
reason: argument mismatch; Integer cannot be converted to Double
1 error

Der Typ »java.lang.Object« wäre zu allgemein, so daß die Methode »intValue()« nicht aufgerufen werden könnte.

Main.java

public final class Main
{

public static void printInt( final java.lang.Object p )
{ java.lang.System.out.println( p.intValue() ); }

public static void main( final java.lang.String[] args )
{ printInt( java.lang.Double.valueOf( "2" ));
printInt( java.lang.Integer.valueOf( "2" )); }}

Protokoll
Main.java:5: error: cannot find symbol
{ java.lang.System.out.println( p.intValue() ); }
^
symbol: method intValue()
location: variable p of type Object
1 error
Wahl des Parametertyps („Goldlöckchen-Prinzip“)
java.lang.Object  -- zu allgemein, Typ hat kein "intValue()", daher
^ erlaubt Uebersetzer ".intValue()"
/_\ nicht
|
|
java.lang.Number -- richtig, hat "intValue" und akzeptiert
^ java.lang.Integer-Argument und
/_\ java.lang.Double-Argument.
|
|
java.lang.Double -- zu speziell, Parameter akzeptiert
java.lang.Integer-Argument
nicht
Die Methode »printInt«
public static void printInt( final java.lang.Number p )
{ java.lang.System.out.println( p.intValue() ); }
Frage an einen Objektnamen
               |
intValue()? | |
V |
|
.----------------------.
| p |
| - |
'----------------------'

Die Methode »printInt« sendet die Frage »intValue()?« an das Objekt »p«, ohne zu wissen, welche Klasse »p« genau hat. Dies ist ein Beispiel für Polymorphie, das zentrale Element der objektorientierten Programmierung.

Polymorphie

Polymorphie erlaubt die Formulierung abstrakter Algorithmen (wie »{ java.lang.System.out.println( p.intValue() ); }«), ohne daß dabei der genaue Typ der beteiligten Objekte (wie »p«) bekannt sein muß, und erlaubt es so, Objekte verschiedener Klassen flexibel miteinander kooperieren zu lassen. In einem späteren Teil des Kurses wird gezeigt werden, daß die Polymorphie es auch erlaubt, die Definition von Signaturen zu erweitern, ohne schon vorhandene Definitionen ändern zu müssen – dies erleichtert die Wartung großer Programme.

Noch ein Beispiel

Das folgende Diagramm zeigt, daß der Typ »java.lang.Object« Obertyp von »java.lang.String« und »java.io.PrintStream« ist und eine Signatur »toString()« enthält.

Typhierarchie
                  .---------------------------.
| java.lang.Object |
|---------------------------|
|---------------------------|
| + toString() |
'---------------------------'
^
/_\
|
|
.----------------'----------------.
| |
.---------------------------. .---------------------------.
| java.lang.String | | java.io.PrintStream |
|---------------------------| |---------------------------|
|---------------------------| |---------------------------|
| + toString() | | + toString() |
'---------------------------' '---------------------------'

Jedes Objekt entscheidet an Hand seiner Klasse selber, was es auf eine Frage antwortet. Das folgende Programm zeigt, daß die Frage »toString()?« bei Versendung an Objekte verschiedener Klassen zu ganz unterschiedlichen Antworten führen kann.

Main.java

public final class Main
{

public static void printString( final java.lang.Object o )
{ java.lang.System.out.println( o.toString() ); }

public static void main( final java.lang.String[] args )
{ printString( "2" );
printString( java.lang.System.out ); }}

transcript
2
java.io.PrintStream@6d06d69c
Frage an einen Objektnamen
               |
toString()? | |
V |
|
.----------------------.
| o |
| - |
'----------------------'

Wir sehen in den obigen Programmen auch wieder Beispiele dafür, daß der Typ eines Ausdrucks nicht mit dem Typ seines Objekts übereinstimmen muß. Beispielsweise hat der Parameter »o« im letzten Programm den Typ »java.lang.Object«, während er für ein Objekt mit einem anderen Typ, wie »java.lang.String« oder »java.io.PrintStream« stehen kann.

»o« ist ein Ausdruck, aber kein Objekt! Das heißt: es ist im allgemeinen nicht bestimmt, für welches Objekt der Name »o« steht, da er im Verlaufe eines Programmes mal für das eine und mal für das andere Objekt stehen kann. Selbst die Klasse dieses Objektes ist nicht bestimmt!

Wir müssen also konstatieren, daß Nachrichten zuerst einmal an einen Ausdruck geschickt werden, und dann von dort aus zu einem Objekt weitergeleitet werden, dessen Klasse und Identität durch den Ausdruck aber nicht unbedingt bestimmt sein müssen. Das folgende Diagramm soll diese Weichenfunktion von Ausdrücken klarstellen.

Darstellung zum Ausdruck »o.toString()«
                                |
|
toString()? | |
V |
|
|
.----------------------.
| o |
| :java.lang.Object |
| ~~~~~~~~~~~~~~~~~ |
'----------------------' Ausdruck
| (hat Referenztyp)
|
|
Zeitpunkt 0 | Zeitpunkt 1
.-------------------'-------------------.
| |
| |
| |
| |
.-----------------------. .-----------------------.
| "2" | | java.lang.System.out |
| : java.lang.String | | : java.io.PrintStream |
| ------------------ | | --------------------- |
'-----------------------' '-----------------------'
Objekt Objekt
(hat Klasse) (hat Klasse)

Die in dem obigen Diagramm dargestellte Laufzeitpolymorphie  erlaubt es dieselbe Nachricht an verschiedene Objekt zu schicken, die sogar verschiedene Klassen (wie »java.lang.String« und »java.io.PrintStream«) haben können. Diese Laufzeitpolymorphie ist der entscheidenden Teil bei der objektorientierten Programmierung! Denn durch sie unterscheidet sich die objektorientierte Programmierung von der Programmierung mit abstrakten Datentypen, mit der sie sonst vieles gemein hat. Die Programmierung mit abstrakten Datentypen erlaubt es schon, Klassen zu bilden und Objekte von Klassen anzulegen, sie erlaubt aber keine Laufzeitpolymorphie.

Objektorientierte Programmierung ist Programmierung mit abstrakten Datentypen und Laufzeitpolymorphie.

Damit der Programmierer vom Verhalten der Objekt beim Empfang einer Nachricht nicht überrascht wird, sollte das Verhalten eines Objektes der Dokumentation seiner Klasse entsprechen und die Dokumentation einer Nachrichtensignatur in einer Klasse sollte eine Spezialfall der Dokumentation einer Methodensignatur in dem Referenztyp des Ausdrucks sein, dessen Wert das Objekt ist.

Das obenstehende Nachrichtenversanddiagramm entspricht dem folgenden Typdiagramm.

Typhierarchie
                  .---------------------------.
| java.lang.Object |
|---------------------------|
|---------------------------|
| + toString() |
'---------------------------'
^
/_\
|
|
.----------------'----------------.
| |
.---------------------------. .---------------------------.
| java.lang.String | | java.io.PrintStream |
|---------------------------| |---------------------------|
|---------------------------| |---------------------------|
| + toString() | | + toString() |
'---------------------------' '---------------------------'

Lokale Variablen

Dasselbe Prinzip kann auch mit lokalen Variablen statt Parametern verwendet werden:

Main.java

public final class Main
{

public static void main( final java.lang.String[] args )
{

final java.lang.Object o = "2";
java.lang.System.out.println( o.toString() ); }}

transcript
2

Die Verwendung von »java.lang.Object« an Stelle von »java.lang.String« in dem obigen Programm hat folgenden Vorteil: Wenn später einmal ein anderes Objekt als »"2"« verwendet werden soll, dann muß der Rest des Programms nicht verändert werden. Eine Änderung ist nur an einer Stelle  nötig.

Main.java

public final class Main
{

public static void main( final java.lang.String[] args )
{

final java.lang.Object o = java.lang.System.out;
java.lang.System.out.println( o.toString() ); }}

transcript
2
java.io.PrintStream@6d06d69c

Compiler-Prüfung

Der Übersetzer prüft bei der Übersetzung der folgenden Methode, daß der Verbaufruf »intValue()« im Typ des Kontexts »p«, also im Typ »java.lang.Number« vorhanden ist.

Methode
public static void printInt( final java.lang.Number p )
{ java.lang.System.out.println( p.intValue() ); }

In einigen Sprachen (nicht aber in Java ) kann solch eine Typ-Prüfung ausgeschaltet werden, indem der Typ des Parameters offengelassen wird. Der Übersetzer würde dann die Methode ohne Prüfung, ob der Verbaufruf »intValue()« im Typ des Kontexts »p« vorhanden ist, übersetzen.

hypothetische Methode
public static void printInt( final p )
{ java.lang.System.out.println( p.intValue() ); }

Falls ein Übersetzer soll tolerant sein sollte, wäre es dann aber möglich, die Methode »printInt« auch mit Argumenten aufzurufen, welche die Nachricht »intValue()?« gar nicht ermöglichen.

Main.txt

public final class Main
{

public static void printInt( final p )
{ java.lang.System.out.println( p.intValue() );
java.lang.System.out.println( "println" ); }

public static void main( final java.lang.String[] args )
{ printInt( "abc" ); }}

In diesem Falle würde die Java -Maschine dann erst bei der Ausführung des Programms  einen Fehler melden.

Konsole
Exception in thread "main" java.lang.NoSuchMethodError: String.intValue()
at Main.main(Main.java:4)

Die Mehrheit der großen Benutzer (Organisationen) der Programmiersprache Java  wünscht es sich aber, daß Fehler durch den falschen Typ eines Arguments schon beim Übersetzen  und nicht erst bei der Ausführung  eines Programms angezeigt werden. Der Übersetzer prüft nämlich beim Übersetzen alle Teile  eines Programms, während manche Teile des Programms nur selten unter bestimmten Bedingungen  ausgeführt werden. Dies bedeutet, daß es schwierig  sein kann, Fehler zu entdecken, die erst bei der Ausführung des Programms auftreten können. Solche Fehler sind gleichzeitig peinlicher, weil sie nicht beim Programmierer auftreten müssen, sondern erst beim Kunden auftreten könnten.

Das folgende Programm zeigt nun, daß Java  Argumente mit falschen Typen (Typen, welche die in einer Methode verwendeten Methoden nicht enthalten) schon bei der Übersetzung erkennt.

Main.java

public final class Main
{

public static void printInt( final java.lang.Number p )
{ java.lang.System.out.println( p.intValue() ); }

public static void main( final java.lang.String[] args )
{ printInt( "abc" ); }}

Konsole
Main.java:6: error: method printInt in class Main cannot be applied to given types;
{ printInt( "abc" ); }}
^
required: Number
found: String
reason: argument mismatch; String cannot be converted to Number
1 error

Das folgende Programmbeispiele zeigt es, daß der Übersetzer es auch gleichzeitig erkennt, wenn eine Methode aufgerufen wird, die im Parameter nicht enthalten ist (genauergesagt: im Typ  des Parameters nicht enthalten ist).

Main.java

public final class Main
{

public static void printInt( final java.lang.Number p )
{ java.lang.System.out.println( p.value() ); }

public static void main( final java.lang.String[] args )
{ printInt( java.lang.Double.valueOf( "2" )); }}

Konsole
Main.java:4: error: cannot find symbol
{ java.lang.System.out.println( p.value() ); }
^
symbol: method value()
location: variable p of type Number
1 error

Der Übersetzer stellt also einerseits sicher, daß das Argument einer Methode auch tatsächlich alle Methoden des Parametertyps enthält, und dann, daß die in der Methode aufgerufenen Methoden auch tatsächlich alle im Parametertyp enthalten sind. Somit stellt der Übersetzer insgesamt sicher, daß die in der Methode aufgerufenen Methoden auch alle im Typ des Arguments enthalten sind.

Diese Typprüfungen schon bei der Übersetzung bilden das Fundament der sogenannten statischen Typsicherheit  von Java.

Man kann sich einen Parameter eines Typs wie einen Wächter vorstellen, der nur Argumente durchläßt, die auch tatsächlich den Parametertyp als Obertyp enthalten.

Statische und dynamische Typen

Die Typen von Ausdrücken werden auch oft als „statische Typen“ bezeichnet, weil sie durch den Quelltext bestimmt sind, und alles, was mit dem Quelltext zu tun hat, als „statisch“ bezeichnet wird, weil der Quelltext bei der Ausführung eines Programms unveränderlich („statisch“) ist.

Die Typen von Objekten werden auch oft als „dynamische Typen“ bezeichnet, weil Objekte erst bei der Ausführung eines Programms existieren, und alles, was mit der Ausführung zu tun hat, als „dynamisch“ bezeichnet wird, weil solche Dinge sich bei der Ausführung eines Programms („dynamisch“) verändern können.

Für die objektorientierte Programmierung  mit Polymorphie ist nur ein dynamisches Typsystem  nötig. Daher gibt es objektorientierte Programmiersprachen (wie Smalltalk ), die kein statisches Typsystem haben.

In Java  gibt es zusätzlich ein statisches Typsystem, weil große Anwender die damit erreichte statische Typsicherheit wünschen. Das Erlernen der Programmiersprache wird aber dadurch erschwert, weil man gleich zwei Typsystem lernen muß: Das statische Typsystem und das dynamische.

Dokumentation von Nachrichtensignaturen

Am Anfang des Kurses hatten wir gelernt, wo wir die Dokumentation einer Signatur finden.

Das Dokumentationsprinzip vom Anfang des Kurses

Dokumentationsprinzpip Die Dokumentation  einer nicht-statischen  Methode findet man unter dem Typ  ihres Kontexts. Die Dokumentation  einer statischen Methode  findet man unter ihrem Kontext.

Tatsächlich wird das Verhalten einer Nachrichtenverarbeitung aber nicht vom Typ des empfangenden Ausdrucks bestimmt, sondern vom Typ des die Nachricht empfangenden Objekts. Dieses Verhalten muß allerdings mit der Dokumentation der Signatur im Typ des Ausdrucks verträglich sein – es muß also ein Spezialfall davon sein. Das neue Dokumentationsprinzip lautet nun:

Dokumentationsprinzpip Die Dokumentation  einer nicht-statischen  Nachrichtensignatur findet man unter dem Typ  des die Nachricht empfangenden Objektes. Die Dokumentation  einer statischen Signatur  findet man unter ihrem Kontext.

Übungsfragen

?   Übungsfrage

Die Methoden namens »printObject« sollen die Textdarstellung eines Objektes ausgeben.

Main.java

public final class Main
{

public static void printObject( final java.io.PrintStream o )
{ java.lang.System.out.println( o.toString() ); }

public static void printObject( final java.lang.String o )
{ java.lang.System.out.println( o.toString() ); }

public static void main( final java.lang.String[] args )
{ printObject( java.lang.System.out );
printObject( "2" ); }}

transcript
java.io.PrintStream@15db9742
2

Die Rümpfe der beiden Methoden namens »printObject« sind einander gleich. Wie können die beiden Deklarationen einer Methode namens »printObject« in dem obigen Programm durch nur eine einzige  Methodendeklaration ersetzt werden?

?   Übungsfragen

Main.java

public final class Main
{

public static void printString( final java.lang.Object o )
{ java.lang.System.out.println( o.toString() ); }

public static void main( final java.lang.String[] args )
{ printString( "2" ); }}

?   Übungsfragen

Main.java

public final class Main
{

public static void printString( final java.lang.Object o )
{ java.lang.System.out.println( o.toString() ); }

public static void main( final java.lang.String[] args )
{ printString( "2" );
printString( java.lang.System.out ); }}

?   Übungsfrage

Welcher Typ wird in dem folgenden Programm an Stelle der Ellipse benötigt, damit das Programm ohne Fehlermeldungen übersetzt werden kann?

Main.java

public final class Main
{

public static void print( final … p )
{ java.lang.System.out.println( p.toString() ); }

public static void main( final java.lang.String[] args )
{ print( new java.lang.String( "3" ));
print( new java.lang.StringBuffer( "3" ));
print( new java.lang.Integer( "3" )); }}

transcript
3
3
3

?   Übungsfrage

Welcher Typ wird in dem folgenden Programm an Stelle der Ellipse benötigt, damit das Programm die gezeigte Ausgabe erzeugt?

Main.java

public final class Main
{

public static void printLength( final … p )
{ java.lang.System.out.println( p.length() ); }

public static void main( final java.lang.String[] args )
{ printLength( new java.lang.String( "Hallo, Welt" ));
printLength( new java.lang.StringBuffer( "Hallo, Welt" ));
printLength( new java.lang.StringBuilder( "Hallo, Welt" )); }}

java.lang.System.out
11
11
11

Refaktor (2) ⃗

Lagern Sie die Anweisungen aus der Methode »start«, welche vor der Anweisung »stage.setScene( new javafx.scene.Scene( vbox ));« stehen, in eine separate Methode »vbox()« aus, so daß die Anweisung »stage.setScene( new javafx.scene.Scene( vbox ));« dann als »stage.setScene( new javafx.scene.Scene( vbox() ));« geschrieben werden kann.

Bemerkung In der Regel sind zwei kleine Methoden  besser als eine große Methode, vorausgesetzt, die Art der Zerlegung ist einigermaßen sinnvoll (so daß jede der neuen Methoden ein klar verständliche Aufgabe hat).

Main.java

public final class Main extends javafx.application.Application
{

public void start( final javafx.stage.Stage stage )
{

final javafx.scene.layout.VBox vbox
= new javafx.scene.layout.VBox();

final javafx.scene.control.TextField text
= new javafx.scene.control.TextField( "text" );
vbox.getChildren().add( text );

final javafx.scene.control.TextField text1
= new javafx.scene.control.TextField( "text" );
vbox.getChildren().add( text1 );

stage.setScene( new javafx.scene.Scene( vbox ));
stage.show(); }}

Refaktor (3) ⃗

Setzen Sie die Zeilentripel, die zu jedem der beiden Textfelder gehören, jeweils in geschweiften Klammern und benennen Sie »text1« dann in »text« um.

Main.java

public final class Main extends javafx.application.Application
{

public void start( final javafx.stage.Stage stage )
{

final javafx.scene.layout.VBox vbox
= new javafx.scene.layout.VBox();

final javafx.scene.control.TextField text
= new javafx.scene.control.TextField( "text" );
vbox.getChildren().add( text );

final javafx.scene.control.TextField text1
= new javafx.scene.control.TextField( "text" );
vbox.getChildren().add( text1 );

stage.setScene( new javafx.scene.Scene( vbox ));
stage.show(); }}

Refaktor (4) ⃗

In dem folgenden Programm finden sich in der Methode »start« zwei Tripel von Zeilen, die einander fast gleich sind. Erstellen Sie eine Methode und rufen Sie diese Methode zwei Mal in geeigneter Weise auf, um schließlich wieder dasselbe Verhalten beobachten zu können, wie bei dem Originalprogramm, aber weniger Wiederholung im Quelltext zu haben.

Main.java

public final class Main extends javafx.application.Application
{

public void start( final javafx.stage.Stage stage )
{

final javafx.scene.layout.VBox vbox
= new javafx.scene.layout.VBox();

final javafx.scene.control.TextField text
= new javafx.scene.control.TextField( "text" );
vbox.getChildren().add( text );

final javafx.scene.control.TextField text1
= new javafx.scene.control.TextField( "text" );
vbox.getChildren().add( text1 );

stage.setScene( new javafx.scene.Scene( vbox ));
stage.show(); }}

Hinweis für den Dozenten  ► N: introduce method

Übungsaufgabe

Hinweis für den Dozenten  ► Diese Übungsaufgabe sollte nicht vor der Nachbesprechung der vorherigen Übungsaufgabe bearbeitet werden.

Schreiben Sie an die Stelle »/* B */« eine Anweisung ein, welche eine Methode mit dem Methodennamen »m« mit dem Textfeld »text« als Argument aufruft.

Fügen sie alsdann an der Stelle »/* A */« eine Deklaration einer statische Klassenmethode mit dem Methodennamen »m« zu der Klasse hinzu, welche ein Textfeld vom Typ »javafx.scene.control.TextField« als Argument akzeptiert. Im Rumpf der Methodendeklaration soll dann die Zeichenfolge jenes Textfeldes ausgegeben werden, und danach soll die Zeichenfolge jenes Textfeldes als die Zeichenfolge »def« festgelegt werden.

public final class Main extends javafx.application.Application
{

/* A */

public void start( final javafx.stage.Stage stage )
{
final javafx.scene.control.TextField text
= new javafx.scene.control.TextField( "" );

/* B */

javafx.application.Platform.exit();
System.exit( 0 ); }}

Seiteninformationen und Impressum   |   Mitteilungsformular  |   "ram@zedat.fu-berlin.de" (ohne die Anführungszeichen) ist die Netzpostadresse von Stefan Ram.   |   Eine Verbindung zur Stefan-Ram-Startseite befindet sich oben auf dieser Seite hinter dem Text "Stefan Ram".)  |   Der Urheber dieses Textes ist Stefan Ram. Alle Rechte sind vorbehalten. Diese Seite ist eine Veröffentlichung von Stefan Ram. Schlüsselwörter zu dieser Seite/relevant keywords describing this page: Stefan Ram Berlin slrprd slrprd stefanramberlin spellched stefanram723362 stefan_ram:723362 Objektparameter in Java Stefan Ram, Berlin, and, or, near, uni, online, slrprd, slrprdqxx, slrprddoc, slrprd723362, slrprddef723362, PbclevtugFgrsnaEnz Erklärung, Beschreibung, Info, Information, Hinweis,

Der Urheber dieses Textes ist Stefan Ram. Alle Rechte sind vorbehalten. Diese Seite ist eine Veröffentlichung von Stefan Ram.
https://www.purl.org/stefan_ram/pub/objektparameter_java