7. Klassen, Objekte, Typen - auf Matthias

Werbung
7. Klassen, Objekte, Typen
7.1
7.2
7.3
7.4
7.5
Klassen zur Programmstrukturierung
Verweise (Zeiger)
Elementare Speicherverwaltung
Verbundtypen
Klassen und Objekte
7.6 Konstruktoren
Klassen (class) werden verwendet
1. zur Strukturierung von Programmen
analog zum Modul in anderen Programmiersprachen
- besonders Modula 2
2. als Typen, die als Schablone für die Erzeugung
von Objekten dienen
→ objektorientierte Programmierung(*)
(*) nicht das einzige Merkmale für OOP, siehe unten
hs / fub - alp2-07 2
Beispiel:
Class Math {
static
static
static
...
static
static
static
static
}
...
}
final double PI = 3.1415926535898
double abs(double a){...}
double cos(double x){...}
double log(double x){...}
int count;
// counts number of calls of random()
{count = 0;} // explizite Initialisierug
double random(){
count++;
... return ...;
Terminologie:
(Statische) Methoden und Variablen (Felder, fields),
Sammelbegriff für beide Arten: Komponenten, Mitglieder
(member)
hs / fub - alp2-07 3
Klassenvariable
z static int count ist wegen static eine
Klassenvariable
z
Explizite Initialisierung durch anonymen Block möglich.
z
Klassenvariablen sind nichtlokal.
z
Es gibt in einem Programm nur ein Exemplar der Variable.
→ deshalb zählen mit count im Bsp. möglich.
Verwunderlich? Bisher eher nicht…
Gültigkeitsbereich
alle vereinbarten Bezeichner sind in der gesamten Klasse
gültig, können aber verdeckt werden…
hs / fub - alp2-07 4
public class NumberCuriosity {
static int oNumber = 077;
static int dNumber = 77;
public static void testeSichtbarkeit(){
int oNumber = 999;
NumberCuriosity.oNumber++;
System.out.println(oNumber+", "+
NumberCuriosity.oNumber);
}
public static void main (String [] args) {
System.out.println(oNumber);
testeSichtbarkeit();
}
} Achtung: nichtlokale Effekte (Nebeneffekte) durch Methode
hs / fub - alp2-07 5
Programm
.. besteht aus einer (selten!) oder mehreren (vielen!) Klassen.
… Module: analog
Punktnotation zur Adressierung von Komponenten anderer
Klassen
Identifier {.Identifier}0n
class MyClass{
static double myFunction(double x) {
return Math.sin(x) * Math.exp(-x);
}
…
}
hs / fub - alp2-07 6
Importe und Benennung
Vollständiger Name (fully qualified name):
Paket-, Klassen- und Komponentenname in Punktnotation (*)
math.myMathPackage.Math.PI
Komponente, hier KONSTANTE
Klassenname (Konvention:groß)
Paketname (Konvention: klein) mit Unterpaket
(*) Pakete können ferner hierarchisch in Unterpaketen organisiert sein
hs / fub - alp2-07 7
… Benennung von Komponenten
import <Klassenbezeichner>;
- single type import -
Komponenten der Klasse können ohne Qualifizierung durch
Paketbezeichner verwendet werden.
import math.myMathPackage.Math;
...{ double res = Math.sin(x); …}
Jetzt kann auf alle öffentlichen Klassen von math ohne
Paketnamen zugegriffen werden:
import math.*;
...{ double res = Math.sin(x); …}
hs / fub - alp2-07 8
7. Klassen, Objekte, Typen
7.1
7.2
7.3
7.4
7.5
Klassen zur Programmstrukturierung
Verweise (Zeiger)
Elementare Speicherverwaltung
Verbundtypen
Klassen und Objekte
7.6 Konstruktoren
Klassendiagramme
Grafische Darstellung von Klassen und deren Beziehungen
mit Hilfe von UML Klassendiagrammen.
"Vererbungsbeziehung"
(später)
aus Wikipedia
hs / fub - alp2-07 10
Bibliotheksklassen
z
Jedes Programmiersprachsystem besitzt
Programmbibiliotheken (Modul- / Klassenbibliotheken)
für häufig benutzte Standardfunktionen.
z
Java: besonders vielfältige Sammlung von Bibliotheksklassen.
Wegen Plattformunabhängigkeit und guter Dokumentation?
z
Bibliotheksschnittstelle definiert die Gesamtheit aller in der
Bibliothek sichtbaren Elemente (Anwendungsprogrammschnittstelle, application programming interface, API)
hs / fub - alp2-07 11
siehe http://java.sun.com/j2se/1.5.0/docs/api/
hs / fub - alp2-07 12
Getrenntes Übersetzen und Binden
z
Getrenntes Übersetzen von Programmbestandteilen Stand
der Technik.
Vorteil: nur geänderte Teile neu zu übersetzen
z
Erfordert Binden (linkage, linking) der Programmteile
zu einem Ganzen
z
Geschieht vor Ausführung durch statischen Binder
(linkage editor) oder dynamisch zur Laufzeit
hs / fub - alp2-07 13
Aufgaben eines Binders
z
Adressumwandlung (address relocation): relative in
absolute Adressen
Programmteile beginnen mit Adresse 0!
Beachte: Adressen sind Adressen im Virtuellen
Adressraum,
Umwandlung in absolute Speicheradressen per Hardware
bei jedem Speicherzugriff (!)
z
Auflösen externer Bezüge, besonders von
Unterprogrammaufrufen
hs / fub - alp2-07 14
Übersetzte Klassendatei
class VMcode
{static int prog()
{ int i;
i = 3;
int j = 5;
return (i+j)*(4+6);
}
}
push(3)
push(5)
plus
push(4)
push(6) Konstanten schon
ausgewertet: gut!
plus
mul
Method VMcode()
0 aload_0
1 invokespecial #3 <Method ....(>
4 return
Method int prog()
0 iconst_3
Lokale Variablen i und j
1 istore_0
2 iconst_5
3 istore_1
4 iload_0
5 iload_1
6 iadd
7 bipush 10
9 imul
10 ireturn
erhält man mit
javap -c <datei>
hs / fub - alp2-07 15
Die Class-Datei
„offset“ hexadezimal
iconst_3 0x6
erster Befehl
der Methode
magic number (version d. Compilers usw
diverse Längen
Ziffern: 0...9,A,B,C,D,E,F
iload_1 0x1b
iadd 0x60
bipush 10
hs / fub - alp2-07 16
Dynamisches Binden
z
Binden während des Ladens des Programms
(Linkage loader)
z
Während der Ausführung: der Maschinencode eines
aufgerufenes Programm wird bei Aufruf von P geladen,
nachdem die Adressanpassung (relocation) stattgefunden
hat.
zur Laufzeit
javac
Sourcecode
VMcode
javac
VMcode
java
Binden/
Laden
Ausführen
= interpretieren
mit VM
Bib
hs / fub - alp2-07 17
7.2 Verweis und Verweistypen
Verweis, Zeiger (reference, pointer) ist ein Wert, der
den Bezug auf eine anonyme oder benannte Variable
erlaubt. Der Wert ist eine (Speicher-) Adresse.
Verweise sind (meist) getypt: Verweistyp* (reference type)
Z.B. Modula:
TYPE intPtr = POINTER TO INTEGER
z.B. C:
int *intPtr
Alle bisherigen Typen waren
Werttypen (value types)
hs / fub - alp2-07 18
Wert- und Verweistypen
Werttyp T: der Name einer Variablen des Typs ist ein Alias für
die Adresse der Variablen
int i=1;
j = i
int j=2;
Zuweisung:
Kopiersemantik
hs / fub - alp2-07 19
Verweistyp T: Name einer Variablen mit Verweistyp T:
Alias für die Adresse der Variablen, die
die Adresse eines Werts (!) des Typs enthält
TYPE iPtr = POINTER TO INTEGER
TYPE jPtr = POINTER TO INTEGER
NEW(iPtr);
NEW(jPtr);
jPtr = iPtr;
INTEGER-Werte noch
undefiniert (!)
Zuweisung:
Referenzsemantik
hs / fub - alp2-07 20
Referenzierung und Dereferenzierung
Modula2: Zeiger ermöglichen Erzeugung und Nutzung
von anonymen Variablen.
VAR i,j: INTEGER;
VAR p1,p2: POINTER TO INTEGER;
NEW(p1);
erzeugt anonyme Variable π und speichert
NEW(p2);
deren Adresse in p1.
i
:= 4;
p2^ := i;
^ ist Dereferenzierungsoperator,
p1 := p2;
j
:= p1^; bezeichnet Wert an der entsprechenden Adresse
hs / fub - alp2-07 21
Nach Ausführung der Anweisungen:
p1
p1=p2
p2
4
NEW(p1)
NEW(p1)
π
4
4
i
j
Hier muss dem Programm dynamisch Speicher zugewiesen
werden (später)
hs / fub - alp2-07 22
Verweise und Adressen in C
Ein Unterschied: benannten Variablen können mit Zeigern
adressiert werden.
Adressoperator & liefert Adresse:
int i;
int *ip;
ip = &i;
Dereferenzierungsoperator *
Adressoperator &
In der Vereinbarung spielt * die Rolle von POINTER TO in
Modula2.
hs / fub - alp2-07 23
Analoges Beispiel in C:
int x = 1, y=2;
int *ip1,*ip2;
ip1 = &x;
ip1 enthält Adresse von x
x
= 4;
ip2 = ip1;
ip2 enthält Wert von ip1 = Adresse von x
*ip2 = 3;
Variable, dessen Adresse ip2 enthält,
erhält Wert 3
y
= *ip1;
Variable j erhält Wert der Adresse, auf die
ip1 zeigt.
Damit: ip1 == &x, ip2==&x, x==3, y==3
⇒ *ip1 ==3, *ip2==3
hs / fub - alp2-07 24
(Typ-)Sicherheit
Adressierung von benannten Objekten gefährlich.
int x = 1, y=2;
int *ip1,*ip2;
ip1 = &x;
y = ip1;
Jetzt enthält y eine Adresse!
Nicht erlaubt: Zuweisung ohne Initialisierung
int *ip;
*ip1 = 100;
Ausschließlich Adressierung anonymer Objekte ist sicherer.
hs / fub - alp2-07 25
Verweise Java (Details später)
Zur Erinnerung:
boolean[] isPrime;
isPrime = new boolean[max + 1];
erzeugt ein Feld mit dem Namen isPrime.
Tatsächlich handelt es sich bei isPrime um einen Verweistyp!
Es gibt keinen Dereferenzierungs- oder Adressoperator in Java!
isPrime[n] dereferenziert implizit !
hs / fub - alp2-07 26
Parameterübergabe
Wenn eine Sprache (wie C oder Java) nur Wertparameter kennt,
kann man mit Verweisen ähnliche Effekte erzielen wie mit
VAR Parametern:
Achtung:C-Code,
swap (x,y) ohne Wirkung
int x,y;
{
int tmp;
tmp=x;
x=y;
y=tmp;
}
…
swap(a,b);
Besser, wenn auch
nicht schön.
swap (px,py)
int *px,*py;
{
int tmp;
tmp=*px;
*px=*py;
*py=tmp;
}
…
swap(&a,&b);
hs / fub - alp2-07 27
7.3 Elementare Speicherverwaltung
z
Vereinbarung einer static Variable veranlasst den
Übersetzer Speicher in der durch den Typ festgelegten
Größe zu reservieren.
class A{
static int i=1;
…
i++; ..}
Übersetzer
..
add 0xf124, 1
…
0xf124
0xf128
Programm
Daten
Die Variable i ist während der Lebensdauer dieser Klasse
gültig.
hs / fub - alp2-07 28
Automatische dynamische Speicherzuweisung
if (…) {…}
else {
int i =1
while (i>0) {
int j = i+1;
…
}
i++;
}
j
i
Stapel
(stack)
Speicherplatz für i und j wird dynamisch, d.h. zur Laufzeit (!)),
und automatisch, auf dem Stapel, einem speziellen
Speicherbereich im Hauptspeicher, angelegt – und wieder
frei gegeben. (C Terminologie: automatic storage)
hs / fub - alp2-07 29
Dynamische (programmierte) Speicherzuteilung
VAR p1 : POINTER TO INTEGER;
...
NEW(p1);
Was passiert hier?
VAR p1…: Übersetzer legt Speicherplatz für einen
Zeiger (Verweis) an (!), ggf. auf Stapel.
Die Ausführung des Befehls NEW(p1) legt dynamisch Speicher für
ein Objekt des Typs (hier INTEGER) an, auf das p1 zeigt und p1
hat diese Adresse als Wert.
?
NEW (p1)
Speicherhalde
(heap)
p1
hs / fub - alp2-07 30
Freigeben von Speicher
Dynamisch zugewiesener ("allozierter")(*) Speicher sollte / muss
freigegeben werden, wenn er nicht mehr gebraucht wird.
Freigabeoperation: DISPOSE (p)
Gibt den Speicher frei, der mit NEW(p) zugewiesen wurde.
Die Größe des freizugebenden Speichers ergibt sich aus
dem Verweistyp.
NULL
p1
DISPOSE(p1)
"hängender Zeiger"
(dangling pointer)
(*) storage allocation
hs / fub - alp2-07 31
Programmierte Speicherzuweisung
Operationen zur dynamischen Speicherzuweisung / -freigabe
nicht notwendig als Befehle der Sprache.
Wegen enger Verbindung zur Betriebssystem:
(unverzichtbare) Bibliotheksfunktionen. C, C++: malloc(),free()
Programmierte Speicherzuweisung gefährlich!
Ohne korrekte Rückgabe Gefahr des Speicherlecks – immer
weniger verfügbarer Speicher.
hs / fub - alp2-07 32
Automatische Freigabe des Speichers
(garbage collection)
• Bei modernen Sprachen wie Java, C# üblich.
• Reduziert Fehleranfälligkeit signifikant.
• Algorithmen nichttrivial und…
• … zeitintensiv
• Inakzeptabel: Unterbrechung der Programmausführung und
Durchkämmen des Speichers auf freizugebende
Speicherbereiche.
• Deshalb: Aufsammeln der freien Bereiche als Hintergrundaktivität. (Algorithmen in Alp3)
hs / fub - alp2-07 33
7.4 Verbundtypen
Bisher: Variable eines Typs kann einen Wert enthalten.
Ausnahme: Feld (array) als Folge fester Länge von Elementen
gleichen Typs.
boolean [] prime = new int[MAX];
Verbundtyp (Produkttyp,Tupeltyp) (structure, record type,…) T:
Wert wT von T setzt sich aus Werten von n Basistypen T1,
…, Tn zusammen.
d.h.:
wT ∈ T1 ¥ T2 ¥ ... ¥ Tn
(Deshalb auch Tupeltyp)
hs / fub - alp2-07 34
Werte von Verbundtypen:
Datensatz, Verbund, Tupel (record*, tuple**, structure)
Verbundtypen (fast) immer mit benannten Komponenten
Modula2:
TYPE MesswertT RECORD Versuchsnr: INTEGER,
Wert: REAL;
VAR Messwert: MesswertT;
C:
typedef struct{int versuchsnr; double wert;}vTyp
vTyp d1,d2;
(*) NICHT: Rekord (!),
(**) besonders in Relationalen Datenbanken
;
Typname
hs / fub - alp2-07 35
Adressierung von Verbundkomponenten
Variablen.Komponentenname
Selektor
IF (Messwert.Versuchsnr > 10) THEN…
if (d1.versuchsnr == 100) {…}
hs / fub - alp2-07 36
Verbunde: dynamisch oder automatisch?
Beides!
VAR x :
RECORDTYP;
VAR recPtr: POINTER TO RECORDTYP;
NEW(recPtr);
Speicher auf
dem Stapel.
Speicher auf
der Halde.
Analog in C
Dagegen C# (!):
Verbunde werden aus Verbundtypen mit dem Operator
new auf dem Stapel erzeugt
⇒ Gültigkeit auf Block begrenzt,
⇒ automatische Speicherbereinigung.
hs / fub - alp2-07 37
7.5 Klassen und Objekte
Klassen (class type) sind Verbundtypen!
aber;
Class MyComplex {
static double re,im;
} ??
Dagegen i
Class Complex {
double re,im;
}
Klassenvariable
unzureichend: nur
eine komplexe Zahl
modelliert!
Klassentyp: Verbundtyp, aus
dem sich beliebig viele
Objekte erzeugen lassen.
hs / fub - alp2-07 38
Objekte sind Verweistypen!
Java
Complex c1,c2;
z
erzeut einen getypten Verweis, der Objekte des Typs
Complex referenzieren kann.
z
erzeugt kein Objekt.
Anfangswert: null , d.h. undefinierter Verweis
z
Erzeugung von Objekten
c1 = new Complex();
Erzeugt wird ein Objekt (Exemplar, instance *) der Klasse
instance [engl.] != Instanz !!
Vorbelegung: c1.re und c1.im haben Standardwert (int: 0)
hs / fub - alp2-07 39
Zugriff auf Komponenten
Variablen, die einen Klassentyp besitzen, sind in Java (und C#)
immer Verweistypen!
Unterschied zu Modula2,
C u.a. !
Es gibt keinen Dereferenzierungsoperator.
Deshalb:
c1.re = 2.0;
Implizite Dereferenzierung bei jedem
Zugriff auf ein Objekt mit Hilfe einer
Variablen vom (Klassen-)typ des Objekts.
Java kennt nur diese Verweise.
hs / fub - alp2-07 40
Klassen und Objekten: ein Beispiel
class Point {
Verbundtyp mit Methoden !
int x,y;
void translate(int dx, int dy) {x+=dx; y+=dy;}
double distance(Point q) {…}
}
Point p1,p2;
Programm//p1.x = 20; // null point exception
abbruch!
Point q1 = new Point();
q1.x=100; q1.y=100;
p1 = new Point();
p2 = new Point();
p1 = q1;
p1.x==100 & p1.y==100 & p1==q1
hs / fub - alp2-07 41
Objekte und Methoden
Methodenaufruf:
p1.translate (10,-5);
wendet die Methode auf das Objekt p1 an und bewirkt
für dieses Objekt einen Effekt:
// p1.x ==110
// p1.y == 95
mehr zur Programmierung
mit Objekten in Abschnitt 8
Objekte als Argumente:
double d = p1.distance (q1);
soll euklidischen Abstand bestimmen.
Angenommen:
{…; q1.x=20; q1=null; return abstand;}
ändert q1 nicht (Wertparameter), aber das Attribut x von q1 !
hs / fub - alp2-07 42
Dualität Klassentyp – Modul
z
z
z
Java: Klasse ist Typschablone zur Erzeugung von Objekten
und Modul, in dem Variablen, Konstanten, Funktionen
zusammengefasst sind.
Statische Komponenten sind unabhängig vom Zustand
(eines Objekts)
Initialisierung beim Laden der Klasse (class loader)
Math:
Class Math {
nur
statische Elemente
static final double PI = 3.1415926535898
static double abs(double a){...}
..}
hs / fub - alp2-07 43
Objekte besitzen Zustand
z
Objektzustand gegeben durch Werte der nichtstatischen
Attribute
class Point {
int x,y;
void translate(int dx, int dy) {x+=dx; y+=dy;}
double distance(Point q) {…}
}
z
Methoden m() können Zustand lesen und / oder verändern.
Falls kein Bezug auf Objektzustand, m() statisch vereinbaren.
z
Beispiel:
Anzahl erzeugter Punktobjekte!
Offensichtlich unabhängig vom Zustand eines Objekts.
hs / fub - alp2-07 44
Dualität einer Klasse (Java)
class MyPoint {
static private int count=0;
static public int getCount(){return count;}
private int x,y;
void translate(int dx, int dy) {x+=dx; y+=dy;}
double distance(MyPoint q) {…}
}
Zugriff auf dynamische Komponenten durch Objektvariablen:
MyPoint p = new MyPoint();
if(p.x > 0) {...}
Zugriff auf statische Komponenten: Klassenname
if(MyPoint.count > 1000) {...} // wg. private nur eingeschränkt
Am Rande: Bei Einhalten Groß-/Kleinkonvention static/dynamic erkennbar
hs / fub - alp2-07 45
Objekt und Klasse
Zugriff auf
Klassenattribute durch
Methode erlaubt.
p1 = new MyPoint(100,100);
p1.translate(10,-10);
p1.count++;
// Manchmal sinnvoll
// meist gefährlich, hier fehlerhaft
MyPoint.count++;
MyPoint.translate(5,15); // Fehler Keine Ausführung
von
nicht-statischen Methoden
unabhängig von einem
Objekt.
Auch: Definition statischer Methoden, die dynamische
Attribute verwenden, verboten.
class MyPoint {…
static void nullify(){
if(count>MAX){x=0; y=0;}
}}
//Fehler.
hs / fub - alp2-07 46
Gleichheit und Ungleichheit
MyPoint p = new MyPoint(1,1);
MyPoint q = new MyPoint(p)
aber:
p != q
Gleichheit von Objekten
a) Identität (der Verweise)
q = p;
b) Gleichheit der Komponentenwerte
boolean
equal(Point p){
return(x==p.x && y==p.y && count==p.count);
}
if (p1.equal(p2){...};
hs / fub - alp2-07 47
Zusammenfassung: Verweistypen und Verbunde in Programmiersprachen
Java
C
(*)
Modula2
C#
Verbundtyp Klasse
class
Struktur
struct
Satztyp
RECORD
class und
struct
Verweistyp
Objektvariable
mit Klassentyp
Alle Typen
Alle Typen
<var> *<type>
POINTER
TO..
Objektvar.,
struct-Expl.,
nicht zwingend
Dereferenzierung
implizit
*<var>=..
..=*<var>
<var>^=..
..=<var>^
Speicherallokation
Halde (heap)
Halde
Kontextabhg.,
malloc(): heap ALLOCATE
Speicherverwaltung
Automatisch
manuell
(Garbage Coll.) free()
(*) gilt auch für C++, dort zusätzlich Klassen, Objekte
manuell
DISPOSE
implizit
class: Halde,
struct: Stapel
(stack)
Automatisch
(Garbage
Coll., stack)
hs / fub - alp2-07 48
7.5 Konstruktoren
Point q1 = new Point();
• erzeugt (*) ein Objekt vom Klassentyp Point mit vordefinierten Werten (Java: int mit 0).
• Point() ist der Standardkonstruktor.
• Jede Klasse besitzt Standardkonstruktor, der nicht vereinbart
wird.
• Andere Konstruktoren mit eigenen Initialisierungen und
überladenem Namen können definiert werden.
Point (int i, int j){x=i; y=j;}
Point p = new Point(70,100);
(*) nicht: 'instantiiert' oder 'instanziiert'!!
hs / fub - alp2-07 49
Technischer Ablauf der Objektkonstruktion
MyName myVar = new MyName(…)
(1) Objekt auf der Halde erzeugen.
(2) Angegebenen Konstruktor ausführen.
(3) Adresse des Objekts zurückgeben und den Wert
der Variable des Typs der Klasse zuweisen.
Beachte: wenn es keine Variable (mehr) gibt, die auf ein Objekt
verweist, ist es für immer verloren! ⇒ Garbage Collection
Point p = new Point(10,15);
p = null;
Dieses Objekt verschwindet
auf Nimmerwiedersehen.
hs / fub - alp2-07 50
Initialisierung von Objekten
Vier Möglichkeiten:
class Foo{
int x,y;}
1.
Implizit mit Voreinstellung
int x,y; //x==0; y==0
2.
Explizite direkte Initialisierung
int x=100,y=100;
3.
Explizite Initialisierung mit anonymem Block
int x,y;
{x=50; y=70;}
4.
Initialisierung durch Konstruktor (am häufigsten)
Foo p = new Foo(10,20)
hs / fub - alp2-07 51
Regeln im Umgang mit Konstruktoren
(1) <Klassenname>() ist der Standardkonstruktor einer
Klasse. Falls kein anderer Konstruktor
<Klassenname>(<parameterliste>) definiert wird,
wird er automatisch generiert. (Sonst nicht !)
(2) Kein return in Konstruktor, kein Ergebnistyp, auch nicht
void.
(3) Methode darf keinen Konstruktor aufrufen – aber umgekehrt.
hs / fub - alp2-07 52
Regeln (2)
(4) Konstruktor darf anderen Konstruktor aufrufen, aber nur
als erste Anweisung in der Form this(…)
this: generische Bezeichnung für das aktuelle Objekt
class MyPoint {
static int count=0;
int x,y;
MyPoint(int i, int j){
this.x=i; this.y=j;
MyPoint.count++;
}
MyPoint(MyPoint p){
this(p.x, p.y);
}
..
}
Dieser Konstruktor wird
aufgerufen!
hs / fub - alp2-07 53
Beachte die Feinheiten!
class MyPoint {
static int count=0;
int x,y;
MyPoint(int i, int j){
this.x=i; this.y=j;
MyPoint.count++;
}
MyPoint(MyPoint p){
count++;
Doppelt
this(p.x, p.y);
}..}
gezählt
Was liefert..?
Point p1=new Point(10,15);
p2=new MyPoint(p1);
boolean b = p1.equal(p2);
Kopie anlegen
hs / fub - alp2-07 54
Herunterladen