7. klassen, objekte, typen · 7. klassen, objekte, typen 7.1 klassen zur programmstrukturierung 7.2...
TRANSCRIPT
7. Klassen, Objekte, Typen
7.1 Klassen zur Programmstrukturierung7.2 Verweise (Zeiger)7.3 Elementare Speicherverwaltung7.4 Verbundtypen7.5 Klassen und Objekte7.6 Konstruktoren
hs / fub - alp2-07 2
Klassen (class) werden verwendet
1. zur Strukturierung von Programmen
2. als Typen, die als Schablone für die Erzeugung von Objekten dienen → objektorientierte Programmierung(*)
(*) nicht das einzige Merkmale für OOP, siehe unten
analog zum Modul in anderen Programmiersprachen - besonders Modula 2
hs / fub - alp2-07 3
Beispiel:Class Math {
static final double PI = 3.1415926535898static double abs(double a){...}static double cos(double x){...}...static double log(double x){...}static int count; // counts number of calls of random()static {count = 0;} // explizite Initialisierugstatic double random(){
count++;... return ...;
}...}
Terminologie: (Statische) Methoden und Variablen (Felder, fields), Sammelbegriff für beide Arten: Komponenten, Mitglieder (member)
hs / fub - alp2-07 4
Klassenvariablestatic int count ist wegen static eine KlassenvariableExplizite Initialisierung durch anonymen Block möglich.Klassenvariablen sind nichtlokal.Es gibt in einem Programm nur ein Exemplar der Variable. → deshalb zählen mit count im Bsp. möglich.
Gültigkeitsbereichalle vereinbarten Bezeichner sind in der gesamten Klassegültig, können aber verdeckt werden…
Verwunderlich? Bisher eher nicht…
hs / fub - alp2-07 5
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 6
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 7
Importe und Benennung
Vollständiger Name (fully qualified name):Paket-, Klassen- und Komponentenname in Punktnotation (*)
(*) Pakete können ferner hierarchisch in Unterpaketen organisiert sein
math.myMathPackage.Math.PI
Paketname (Konvention: klein) mit Unterpaket
Klassenname (Konvention:groß)
Komponente, hier KONSTANTE
hs / fub - alp2-07 8
… Benennung von Komponenten
import <Klassenbezeichner>;- single type import -
Komponenten der Klasse können ohne Qualifizierung durchPaketbezeichner verwendet werden.
import math.myMathPackage.Math;...{ double res = Math.sin(x); …}
import math.*; ...{ double res = Math.sin(x); …}
Jetzt kann auf alle öffentlichen Klassen von math ohne Paketnamen zugegriffen werden:
7. Klassen, Objekte, Typen
7.1 Klassen zur Programmstrukturierung7.2 Verweise (Zeiger)7.3 Elementare Speicherverwaltung7.4 Verbundtypen7.5 Klassen und Objekte7.6 Konstruktoren
hs / fub - alp2-07 10
KlassendiagrammeGrafische Darstellung von Klassen und deren Beziehungenmit Hilfe von UML Klassendiagrammen.
aus Wikipedia
"Vererbungs-beziehung"(später)
hs / fub - alp2-07 11
Bibliotheksklassen
Jedes Programmiersprachsystem besitzt Programmbibiliotheken (Modul- / Klassenbibliotheken) für häufig benutzte Standardfunktionen.
Java: besonders vielfältige Sammlung von Bibliotheksklassen.Wegen Plattformunabhängigkeit und guter Dokumentation?
Bibliotheksschnittstelle definiert die Gesamtheit aller in der Bibliothek sichtbaren Elemente (Anwendungsprogramm-schnittstelle, application programming interface, API)
hs / fub - alp2-07 12siehe http://java.sun.com/j2se/1.5.0/docs/api/
hs / fub - alp2-07 13
Getrenntes Übersetzen und Binden
Getrenntes Übersetzen von Programmbestandteilen Stand der Technik. Vorteil: nur geänderte Teile neu zu übersetzen
Erfordert Binden (linkage, linking) der Programmteilezu einem Ganzen
Geschieht vor Ausführung durch statischen Binder(linkage editor) oder dynamisch zur Laufzeit
hs / fub - alp2-07 14
Aufgaben eines Binders
Adressumwandlung (address relocation): relative in absolute Adressen
Programmteile beginnen mit Adresse 0!
Beachte: Adressen sind Adressen im Virtuellen Adressraum,Umwandlung in absolute Speicheradressen per Hardwarebei jedem Speicherzugriff (!)
Auflösen externer Bezüge, besonders von Unterprogrammaufrufen
hs / fub - alp2-07 15
Übersetzte Klassendatei
class VMcode{static int prog()
{ int i;i = 3; int j = 5;return (i+j)*(4+6);
}}
Method VMcode()0 aload_01 invokespecial #3 <Method ....(>4 return
Method int prog()0 iconst_31 istore_02 iconst_53 istore_14 iload_05 iload_16 iadd7 bipush 109 imul10 ireturn
push(3)push(5)pluspush(4)push(6)plusmul
Konstanten schonausgewertet: gut!
Lokale Variablen i und j
erhält man mit javap -c <datei>
hs / fub - alp2-07 16
Die Class-Datei„offset“ hexadezimal
magic number (version d. Compilers usw
diverse Längen
iadd 0x60iload_1 0x1biconst_3 0x6erster Befehl der Methode
bipush 10
Ziffern: 0...9,A,B,C,D,E,F
hs / fub - alp2-07 17
Dynamisches Binden
Binden während des Ladens des Programms (Linkage loader)
Während der Ausführung: der Maschinencode eines aufgerufenes Programm wird bei Aufruf von P geladen,nachdem die Adressanpassung (relocation) stattgefunden hat.
Source-code
javac
javac
VM-code
VM-code
zur Laufzeit
Bib
Binden/Laden
Ausführen= interpret-
ierenmit VM
java
hs / fub - alp2-07 18
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 19
Wert- und Verweistypen
Werttyp T: der Name einer Variablen des Typs ist ein Alias für die Adresse der Variablen
int i=1;
int j=2;
j = i
Zuweisung:Kopiersemantik
hs / fub - alp2-07 20
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
NEW(jPtr);
TYPE jPtr = POINTER TO INTEGER
NEW(iPtr);
jPtr = iPtr;Zuweisung:Referenzsemantik
INTEGER-Werte nochundefiniert (!)
hs / fub - alp2-07 21
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 speichertNEW(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 22
Nach Ausführung der Anweisungen:
p1 p2
4 4
i jπ
NEW(p1)
p1=p2
Hier muss dem Programm dynamisch Speicher zugewiesen werden (später)
4
NEW(p1)
hs / fub - alp2-07 23
Verweise und Adressen in C
Ein Unterschied: benannten Variablen können mit Zeigern adressiert werden.
Adressoperator & liefert Adresse:int i; int *ip; Dereferenzierungsoperator *ip = &i; Adressoperator &
In der Vereinbarung spielt * die Rolle von POINTER TO in Modula2.
hs / fub - alp2-07 24
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 3y = *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
Analoges Beispiel in C:
hs / fub - alp2-07 25
(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 Initialisierungint *ip;
*ip1 = 100;
Ausschließlich Adressierung anonymer Objekte ist sicherer.
hs / fub - alp2-07 26
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 27
Parameterübergabe
Wenn eine Sprache (wie C oder Java) nur Wertparameter kennt,kann man mit Verweisen ähnliche Effekte erzielen wie mitVAR Parametern:
swap (x,y)int x,y;{ int tmp;
tmp=x;x=y;y=tmp;
}…swap(a,b);
Achtung:C-Code, ohne Wirkung swap (px,py)
int *px,*py;{ int tmp;
tmp=*px;*px=*py;*py=tmp;
}…swap(&a,&b);
Besser, wenn auch nicht schön.
hs / fub - alp2-07 28
7.3 Elementare Speicherverwaltung
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++; ..}
..add 0xf124, 1…0xf124 0xf128
Programm
Daten
Übersetzer
Die Variable i ist während der Lebensdauer dieser Klasse gültig.
hs / fub - alp2-07 29
Automatische dynamische Speicherzuweisung
if (…) {…}else {int i =1while (i>0) {int j = i+1;…}i++;}
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)
ij
Stapel(stack)
hs / fub - alp2-07 30
Dynamische (programmierte) Speicherzuteilung
VAR p1 : POINTER TO INTEGER; ...NEW(p1);
Was passiert hier?
VAR p1…: Übersetzer legt Speicherplatz für einenZeiger (Verweis) an (!), ggf. auf Stapel.
Die Ausführung des Befehls NEW(p1) legt dynamisch Speicher fürein Objekt des Typs (hier INTEGER) an, auf das p1 zeigt und p1hat diese Adresse als Wert.
p1? NEW (p1) Speicherhalde
(heap)
hs / fub - alp2-07 31
Freigeben von Speicher
Dynamisch zugewiesener ("allozierter")(*) Speicher sollte / mussfreigegeben 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 ausdem Verweistyp.
p1DISPOSE(p1)
"hängender Zeiger"(dangling pointer)
NULL
(*) storage allocation
hs / fub - alp2-07 32
Operationen zur dynamischen Speicherzuweisung / -freigabenicht notwendig als Befehle der Sprache.
Wegen enger Verbindung zur Betriebssystem: (unverzichtbare) Bibliotheksfunktionen. C, C++: malloc(),free()
Programmierte Speicherzuweisung
Programmierte Speicherzuweisung gefährlich!Ohne korrekte Rückgabe Gefahr des Speicherlecks – immer weniger verfügbarer Speicher.
hs / fub - alp2-07 33
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 undDurchkämmen des Speichers auf freizugebende Speicherbereiche.
• Deshalb: Aufsammeln der freien Bereiche als Hintergrund-aktivität. (Algorithmen in Alp3)
hs / fub - alp2-07 34
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 35
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 d1,d2;
(*) NICHT: Rekord (!),(**) besonders in Relationalen Datenbanken
Typname
vTyp
hs / fub - alp2-07 36
Adressierung von Verbundkomponenten
Variablen.Komponentenname
IF (Messwert.Versuchsnr > 10) THEN…
Selektor
if (d1.versuchsnr == 100) {…}
hs / fub - alp2-07 37
Verbunde: dynamisch oder automatisch?
Beides!
VAR x : RECORDTYP; VAR recPtr: POINTER TO RECORDTYP;NEW(recPtr);
Speicher aufdem Stapel.
Speicher aufder Halde.
Analog in C
Dagegen C# (!):Verbunde werden aus Verbundtypen mit dem Operatornew auf dem Stapel erzeugt ⇒ Gültigkeit auf Block begrenzt, ⇒ automatische Speicherbereinigung.
hs / fub - alp2-07 38
7.5 Klassen und Objekte
Klassen (class type) sind Verbundtypen!
aber; Class MyComplex {
static double re,im;} ??
Klassenvariable unzureichend: nur eine komplexe Zahlmodelliert!
Dagegen i Class Complex {
double re,im;}
Klassentyp: Verbundtyp, ausdem sich beliebig vieleObjekte erzeugen lassen.
hs / fub - alp2-07 39
Objekte sind Verweistypen!
Complex c1,c2;
erzeut einen getypten Verweis, der Objekte des Typs Complex referenzieren kann. erzeugt kein Objekt.Anfangswert: null , d.h. undefinierter Verweis
Erzeugung von Objektenc1 = new Complex();
Vorbelegung: c1.re und c1.im haben Standardwert (int: 0)
Java
Erzeugt wird ein Objekt (Exemplar, instance *) der Klasseinstance [engl.] != Instanz !!
hs / fub - alp2-07 40
Zugriff auf Komponenten
Variablen, die einen Klassentyp besitzen, sind in Java (und C#) immer Verweistypen!
Es gibt keinen Dereferenzierungsoperator.
Unterschied zu Modula2,C u.a. !
Deshalb: c1.re = 2.0; Implizite Dereferenzierung bei jedem
Zugriff auf ein Objekt mit Hilfe einerVariablen vom (Klassen-)typ des Objekts.
Java kennt nur diese Verweise.
hs / fub - alp2-07 41
Klassen und Objekten: ein Beispiel
Point p1,p2;//p1.x = 20; // null point exceptionPoint q1 = new Point();q1.x=100; q1.y=100;p1 = new Point();p2 = new Point();p1 = q1;
class Point { int x,y;void translate(int dx, int dy) {x+=dx; y+=dy;}double distance(Point q) {…}
}
Programm-abbruch!
p1.x==100 & p1.y==100 & p1==q1
Verbundtyp mit Methoden !
hs / fub - alp2-07 42
Objekte und Methoden
Methodenaufruf:p1.translate (10,-5);
wendet die Methode auf das Objekt p1 an und bewirktfür dieses Objekt einen Effekt: // p1.x ==110// p1.y == 95
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 !
mehr zur Programmierungmit Objekten in Abschnitt 8
hs / fub - alp2-07 43
Dualität Klassentyp – Modul
Java: Klasse ist Typschablone zur Erzeugung von Objektenund Modul, in dem Variablen, Konstanten, Funktionenzusammengefasst sind.Statische Komponenten sind unabhängig vom Zustand(eines Objekts)Initialisierung beim Laden der Klasse (class loader)
Class Math {
static final double PI = 3.1415926535898static double abs(double a){...}..}
Math: nurstatische Elemente
hs / fub - alp2-07 44
Objekte besitzen Zustand
Objektzustand gegeben durch Werte der nichtstatischenAttribute
Methoden m() können Zustand lesen und / oder verändern. Falls kein Bezug auf Objektzustand, m() statisch vereinbaren.Beispiel: Anzahl erzeugter Punktobjekte!Offensichtlich unabhängig vom Zustand eines Objekts.
class Point { int x,y;void translate(int dx, int dy) {x+=dx; y+=dy;}double distance(Point q) {…}
}
hs / fub - alp2-07 45
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: Klassennameif(MyPoint.count > 1000) {...} // wg. private nur eingeschränkt
Am Rande: Bei Einhalten Groß-/Kleinkonvention static/dynamic erkennbar
hs / fub - alp2-07 46
Objekt und Klasse
p1 = new MyPoint(100,100);p1.translate(10,-10);p1.count++; // Manchmal sinnvoll
// meist gefährlich, hier fehlerhaftMyPoint.count++; MyPoint.translate(5,15); // Fehler
Zugriff auf Klassenattribute durch Methode erlaubt.
Keine Ausführung vonnicht-statischen Methodenunabhängig von einemObjekt.
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 47
Gleichheit und Ungleichheit
MyPoint p = new MyPoint(1,1);MyPoint q = new MyPoint(p)
aber:p != q
Gleichheit von Objektena) Identität (der Verweise)
q = p;
b) Gleichheit der Komponentenwerteboolean equal(Point p){
return(x==p.x && y==p.y && count==p.count);}
if (p1.equal(p2){...};
hs / fub - alp2-07 48
Zusammenfassung: Verweistypen und Verbunde in Programmiersprachen
Automatisch(GarbageColl., stack)
manuellDISPOSE
manuellfree()
Automatisch(Garbage Coll.)
Speicher-verwaltung
class: Halde,struct: Stapel
(stack)
HaldeALLOCATE
Kontextabhg.,malloc(): heap
Halde (heap)Speicher-allokation
implizit<var>^=....=<var>^
*<var>=....=*<var>
implizitDereferenz-ierung
Objektvar.,struct-Expl., nicht zwingend
Alle TypenPOINTER TO..
Alle Typen<var> *<type>
Objektvariablemit Klassentyp
Verweistyp
class undstruct
SatztypRECORD
Strukturstruct
Klasseclass
Verbundtyp
C#Modula2C (*)Java
(*) gilt auch für C++, dort zusätzlich Klassen, Objekte
hs / fub - alp2-07 49
7.5 Konstruktoren
• erzeugt (*) ein Objekt vom Klassentyp Point mit vordefinier-ten 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 q1 = new Point();
(*) nicht: 'instantiiert' oder 'instanziiert'!!
Point (int i, int j){x=i; y=j;}Point p = new Point(70,100);
hs / fub - alp2-07 50
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 Objektverweist, ist es für immer verloren! ⇒ Garbage Collection
Point p = new Point(10,15);p = null;
Dieses Objekt verschwindetauf Nimmerwiedersehen.
hs / fub - alp2-07 51
Initialisierung von Objekten
Vier Möglichkeiten:
1. Implizit mit Voreinstellung int x,y; //x==0; y==0
2. Explizite direkte Initialisierungint x=100,y=100;
3. Explizite Initialisierung mit anonymem Blockint x,y;{x=50; y=70;}
4. Initialisierung durch Konstruktor (am häufigsten)Foo p = new Foo(10,20)
class Foo{int x,y;}
hs / fub - alp2-07 52
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 53
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 54
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){
this(p.x, p.y);}..}
count++; Doppelt gezählt
Was liefert..? Point p1=new Point(10,15);p2=new MyPoint(p1);boolean b = p1.equal(p2); Kopie anlegen