Johann Wolfgang Goethe-Universität Professur für Graphische Datenverarbeitung Fachbereich Informatik und Mathematik Prof. Dr. Detlef Krömker Ashraf Abu Baker [email protected] Java-Intensivkurs WS07/08 Folie 1 Referenzen in Java Unterschied zwischen einer primitiven Variablen und einer Referenzvariablen: public class Student { public String name;//Referenzvariable (Objektreferenz) public Date gebDatum;// Referenzvariable (Objektreferenz) public String studiengang;// Referenzvariable (Objektreferenz) public int semesteranzahl; //primitive Variable } Student student = new Student("Alex", null, "BWL",3); semesteranzahl speichert den tatsächlichen Wert der Variablen (3) studiengang speichert eine Referenz auf ein String-Objekt, dessen Wert „BWL“ ist Java-Intensivkurs WS07/08 Folie 2 Referenzen in Java Student student = new Student("Alex", null, "BWL",3); Der new-Operator liefert eine Referenz auf das erzeugte Objekt zurück Die Referenz wird dann in der Variablen student gespeichert Java-Intensivkurs WS07/08 Folie 3 Referenzen Man sagt, daß die Variable das Objekt referenziert bzw. darauf zeigt In manchen Implementierungen der JVM wird eine Referenz als Speicheradresse implementiert Eine Referenzvariable speichert dann die Speicheradresse ihres Objektes null-Referenz Zeigt auf kein Objekt und speichert den Wert null Java-Intensivkurs WS07/08 Folie 4 Referenzen Referenzvariablen werden standardmäßig mit null initialisiert bevor ihnen ein Objekt zugewiesen wird Java-Intensivkurs WS07/08 Folie 5 this & super Neben den eigenen und geerbten Attributen einer Klasse, verfügen die Instanzmethoden und die Konstruktoren über zwei weitere Referenzen this: - Referenz auf das Objekt selbst super: - Referenz auf das Objekt der Oberklasse Java-Intensivkurs WS07/08 Folie 6 this this-Referenz wird verwendet zur: Unterscheidung zwischen einer Objektvariablen und einer übergebenen Variablen innerhalb einer Methode oder eines Konstruktors public Line(float x2, float y2){ this.x2=x2; this.y2=y2; } - x2 ist der übergebene Parameter - this.x2 ist das Objektattribut, die ebenfalls x2 heißt Java-Intensivkurs WS07/08 Folie 7 super Analog kann innerhalb einer Klasse mit super auf die Attribute und Methoden der Oberklasse zugegriffen werden public void translate(float dx, float dy) { x2 += dx; y2 += dy; // Wiederverwendung des Codes der Oberklasse super.translate(dx, dy); } Java-Intensivkurs WS07/08 Folie 8 this(), super() public Line(float x2, float y2) { this.x2 = x2; this.y2 = y2; } public Line(float x1, float y1,float x2, float y2){ this(x2,y2);//Aufruf des eigenen Konstruktors //Line(float x2, float y2) this.x1=x1; this.y1=y1; } Java-Intensivkurs WS07/08 Folie 9 super() sdfadsf public Line(float x1, float y1,float x2, float y2){ super(x1,y1);//Aufruf des Konstruktors der Oberklasse this.x2=x2; this.y2=y2; } Aufruf von this() und super() muss als erste Anweisung im Konstruktor erfolgen Aufruf von this.eineMethode() oder super.eineMethode() muss nicht als erste Anweisung erfolgen Java-Intensivkurs WS07/08 Folie 10 Klassen- & Instanzattribute Zwei Arten von Attributen: Klassen- und Instanzattribute Klassenattribute (statische Attribute): Werden mit dem Schlüsselwort static deklariert public static String vorgesetzter; Java-Intensivkurs WS07/08 Folie 11 Klassen- & Instanzattribute public class Mitarbeiter { public static String vorgesetzter="Oliver P.";//Klassenvariable public String abteilung;//Instanzvariable //statische Methode public static void vorgesetzterWechsel(String neuerVorgesetzter) { vorgesetzter = neuerVorgesetzter; } public void abteilungWechsel(String neueAbteilung){ abteilung=neueAbteilung; } Java-Intensivkurs WS07/08 Folie 12 Klassen- & Instanzattribute public static void main(String [] str){ Mitarbeiter nadia=new Mitarbeiter("Nadia O.","Marketing"); Mitarbeiter klaus=new Mitarbeiter("Klaus M.", "Controlling"); nadia.abteilungwechsel("Finanz"); klaus.vorgesetzterWechsel("Paul J."); System.out.println(nadia.abteilung); System.out.println(klaus.abteilung); System.out.println(nadia.vorgesetzter); System.out.println(klaus.vorgesetzter); }} Ausgabe: Finannz Controlling Paul J. Paul J. Java-Intensivkurs WS07/08 Folie 13 Klassenattribute Sind an die Existenz eines Objektes nicht gebunden Von jedem statischen Attribut v existiert genau eine einzige Kopie für alle Objekte der Klasse Alle Objekte sehen den gleichen Wert für v. Zugriff über: Klassennamen z.B. Mitrabeiter.vorgesetzter Instanznamen nadia.vorgesetzter Java-Intensivkurs WS07/08 Folie 14 Instanzattribute (nicht statische Attribute) Jedes Objekt speichert eine eigene Kopie seiner Objektattribute Die Änderung des Wertes eines Instanzattributes in einem Objekt hat keine Auswirkung auf die anderen Objekte Sind an die Existenz eines Objektes gebunden Zugriff über Klassenamen z.B. Mitarbeiter.name nicht möglich Java-Intensivkurs WS07/08 Folie 15 Klassenmethoden (statische Methoden) Wird mit dem Schlüsselwort static Ist an die Existenz eines Objektes nicht gebunden Kann über den Klassennamen und die Objektreferenz aufgerufen werden //statische Methode public static void vorgesetzterWechsel(String neuerVorgesetzter){ vorgesetzter = neuerVorgesetzter; } public static void main(String [] str) Math.sin(a); Math.cos(a); Math.sqrt(a) Float.parseFloat(s) Java-Intensivkurs WS07/08 Folie 16 Instanzmethoden (nicht statische Methoden) Ist an die Existenz eines Objektes nicht gebunden Kann nur über ein Objektreferenz aufgerufen werden Java-Intensivkurs WS07/08 Folie 17 Statische Initialisierer Konstruktoren werden in der Regel verwendet um Variablen zu initialisieren Für komplexe Initialisierung von Klassenvariablen können sog. statische Initialisierer verwendet werden Codeblöcke innerhalb einer Klasse, die mit dem Schlüsselwort static deklariert sind Werden nur ein einziges Mal beim Laden einer Klasse aufgerufen Java-Intensivkurs WS07/08 Folie 18 Statische Initialisierer Dürfen nur auf die Klassenattribute zugreifen und haben somit weder Zugriff auf die this-Referenz noch auf die Instanzattribute der Klasse Eine Klasse kann beliebig viele statische Initialisierer enthalten. Java-Intensivkurs WS07/08 Folie 19 Statische Initialisierer public class InitializationDemo { //Klassenvariablen public static Date date; public static int classLuckyNumber; public static int numberOfCreatedInstances; static{//Statischer Initialisierer date=Calendar.getInstance().getTime(); Random rand=new Random(); int number=rand.nextInt(10); classLuckyNumber=number*number; } } Java-Intensivkurs WS07/08 Folie 20 Nicht statische Initialisierer Sie ähneln Konstruktoren Werden unmittelbar vor dem Aufruf eines Konstruktors aufgerufen Werden zur Initialisierung von Instanz- und Klassenattributen verwendet Dürfen auf die this-Referenz zugreifen Eine Klasse kann beliebig viele Initialisierer enthalten Java-Intensivkurs WS07/08 Folie 21 Nicht statische Initialisierer public class InitializationDemo { public int instanceNumber;//Instanzvariable public int instanceLuckyNumber;//Instanzvariable {//nicht-statischer Initialisierer Random rand=new Random(); instanceNumber=rand.nextInt(10); System.out.println(); this.instanceLuckyNumber=rand.nextInt(10); } Java-Intensivkurs WS07/08 Folie 22 Initialisierungsreihenfolge Beim Laden einer Klasse: 1. Alle statischen Attribute werden in der Reihenfolge initialisiert, in der sie in ihrer Klasse vorkommen 2. Aufruf der statischen Initialisierer Folgendes passiert, wenn ein Objekt mit dem new-Operator instanziiert werden soll: 1. Instanzattribute werden initialisiert 2. Nicht statischen Initialisierer werden aufgerufen 3. Aufruf des Konstruktors Beispiel: Siehe InitializationDemo.java Java-Intensivkurs WS07/08 Folie 23 Call-By-Reference oder Call-By-Value? Übergabe von primitiven Variablen: JVM stellt eine Kopie der Variablen und übergibt sie an die Methode Veränderung der Kopie innerhalb der Methode hat keine Wirkung auf den Variablenwert Übergabe von Referenzen: Eine Kopie der Referenz (nicht das Objekt) wird erstellt und an die Methode übergeben Jede Änderung des Objektes innerhalb der Methode ist nach außen sichtbar Java-Intensivkurs WS07/08 Folie 24 Call-By-Reference oder Call-By-Value? Fazit: Parameterübergabe erfolgt per call-by-value Siehe CallByValue.java Java-Intensivkurs WS07/08 Folie 25 Pakete (packages) Package: Sammlung von logisch zusammengehörenden Klassen, Interfaces und anderen Typen Dienen der logischen Gruppierung von Klassen In anderen Programmiersprachen: Programmierbibliotheken Alle Klassen der Java-API sind in Pakete unterteilt - Z.B. die Math, String, Wrapper-Klassen in java.lang Java-Intensivkurs WS07/08 Folie 26 Pakete Ein Paketname besteht aus mehreren durch Punkt getrennten Bezeichnern: //package declaration package de.frankfurt.uni.cs.gdv.visian3d.datastructures.trees; Physikalisch werden Pakte auf eine hierarchische Verzeichnisstruktur abgebildet: Jeder Bezeichner entspricht dabei einem Verzeichnis Verzeichnisse sind ineinander verschachtelt Java-Intensivkurs WS07/08 Folie 27 Pakete Der voll qualifizierte Name einer Klasse A innerhalb des Paketes de.frankfurt.uni.cs.gdv.datastructures.trees ist de.frankfurt.uni.cs.gdv.datastructures.trees.A java.lang.String ist der voll qualifizierte Name der Klasse String Die Java-API 6.0 enthält etwa 202 Pakete, die 3777 Klassen und Interfaces umfassen Siehe Demo zum anlegen von Paketen Java-Intensivkurs WS07/08 Folie 28 Import Will eine Klasse z.B. die Klassen oder die Interfaces, eines Paketes verwenden, so müssen diese durch eine import-Anweisung importiert werden, ehe sie benutzt werden können import java.util.Random; Eine Klasse zu importieren bedeutet sie samt ihren Attributen und Methoden verfügbar zu machen Ihr Name wird in den Namensraum der Codedatei eingefügt Java-Intensivkurs WS07/08 Folie 29 Import Nur Klassen, die nicht im eigenen Paket liegen müssen importiert werden Ausnahme stellen hier die Bestandteile des Pakets java.lang Da dieses Paket eines der wichtigsten Pakete der JavaAPI ist werden alle in ihm enthaltenen Klassen vor jedem Compilerlauf automatisch importiert //importiert alle Klassen und Interfaces import java.util.*; //importiert ArrayList import java.util.ArrayList; Java-Intensivkurs WS07/08 Folie 30 Statischer Import Gibt es erst seit Version 5 Außerhalb einer Klasse können ihre statischen Funktionen und Konstanten nur über den Klassennamen angesprochen werden long longMaxValue=Long.MAX_VALUE; Werden die Bestandteile einer Klasse statisch importiert, so können ihre statischen Methoden und Attribute ohne Klassennamen sofort benutzt werden Java-Intensivkurs WS07/08 Folie 31 Statischer Import //non static import of java.lang.Math import java.lang.Math.*; //eigentlich überflüssig class WithoutStaticImport{ public static void main(String... args) { System.out.println("Wurzel aus "+Math.PI+" ist "+Math.sqrt(Math.PI)); }} //static import of java.lang.Math import static java.lang.Math.*; public class StaticImport { public static void main(String... args) { System.out.println("Wurzel aus "+PI+" ist "+sqrt(PI)); }} Java-Intensivkurs WS07/08 Folie 32 Datenkapselung und Modifikatoren (modifier) Durch Datenkapselung sollen einem Objekt nur diejenigen Bestandteile einer Klasse zugänglich gemacht werden, die für das Objekt relevant sind Alles Andere bleibt verborgen Zur Unterstützung des Datenkapselungsaspektes definiert Java sog. Modifier Java-Intensivkurs WS07/08 Folie 33 Modifier Modifier: Schlüsselwörter Teilen dem Compiler Informationen mit, wie z.B. Sichtbarkeit, Veränderbarkeit und Lebensdauer von Klassen, Variablen, Konstruktoren, Methoden und Initialisierer //modifier public, private, protected, final, abstract, static, native, transient, synchronized, volatile public, private und protected werden als accessModifier (Zugriffsmodifikatoren) bezeichnet Java-Intensivkurs WS07/08 Folie 34 Modifier Features einer Klasse: Variable, Methode, Konstruktor oder die Klasse selbst Auf als public deklarierte Features kann in jeder Klasse ohne Einschränkung zugegriffen werden private Features können nur innerhalb ihrer eigenen Klasse verwendet werden Java-Intensivkurs WS07/08 Folie 35 Modifier Wird ein Feature ohne Modifier deklariert, so kann auf dieses nur innerhalb von Klassen zugegriffen werden, die im eigenen Paket liegen Man spricht hier von einem default-Zugriff protected: Nur zur Deklaration von Attributen, Methoden und Konstruktoren (nicht für Klassen) Auf ein protected-Feature einer Klasse kann innerhalb aller Klassen seines Pakets uneingeschränkt zugegriffen werden Java-Intensivkurs WS07/08 Folie 36 protected Außerhalb vom eigenen Paket können nur Unterklassen auf das Feature zugreifen, und zwar eingeschränkt Eingeschränkt bedeutet: - Ein Zugriff ist nur außerhalb von Methoden und Konstruktoren erlaubt: Java-Intensivkurs WS07/08 Folie 37 protected package modifier1; public class ModifierClass { protected byte protectedVar = 3; } package modifier1; public class ForignClassInTheSamePackage { public static void main(String... arg) { System.out.println(modifier.protectedVar); }} Java-Intensivkurs WS07/08 Folie 38 protected package modifier2; import modifier1.ModifierClass; public class SubClassOfModifierClass extends ModifierClass { byte protected1=protectedVar;// erlaubter Zugriff auf } public static void main(String... arg) { System.out.println(modifier.protectedVar);//Kompilierfehler } } Java-Intensivkurs WS07/08 Folie 39 final Kann für Klassen, Variablen, und Methoden verwendet werden final-Klasse kann nicht abgeleitet werden: - Beispiel für eine final-Klasse ist die Klasse java.lang.Math public class MyMath extends Math{//Kompilierfehler } Kompilierfehler: The Type MyMath cannot subclass the final class Math Der Wert einer final-Variablen kann nach ihrer Initialisierung nicht mehr verändert werden Math.PI=22/7f; Fehlermeldung: The final field Math.PI cannot be assigned. Java-Intensivkurs WS07/08 Folie 40 final final-Methoden dürfen nicht überschrieben werden. public class Final { public int x=2; public final void setX(int x){this.x=x;} public final void setX(){this.x=x;} } class FinalApplication extends Final{ public final void setX(){//Kompilierfehler } public static void main(String ...strings ){ final Final x=new Final(); x.x=2; } } Kompilierfehler: Cannot override the final method. Java-Intensivkurs WS07/08 Folie 41 Abstrakte Klassen und Methoden Es kommt häufig vor, dass der Programmierer das Verhalten einer Methode in einer Superklasse nicht definieren kann Beispiel: Java-Intensivkurs WS07/08 Folie 42 Abstrakte Klassen und Methoden public abstract class GeometricObject { public public public public public public static final int CIRCLE=0; static final int RECTANGLE=1; static final int TRIANGLE=2; static final int UNDEFINED=-1; int type= UNDEFINED; abstract float getSurface();//abstract method public int getType(){//concrete method return type; } } Java-Intensivkurs WS07/08 Folie 43 Abstrakte Klassen und Methoden Die Methode getSurface() der Klasse GeometricObject soll die Fläche des geometrischen Objektes berechnen und zurück liefern Da die Fläche eines geometrischen Objektes von seiner konkreten Implementierung abhängt, ist eine sinnvolle Implementierung der Methode getSurface() in der Oberklasse nicht möglich In so einem Fall wird die Methode als abstract deklariert Java-Intensivkurs WS07/08 Folie 44 Abstrakte Klassen und Methoden class Rectangle extends GeometricObject{ public float width; public float height; public Rectangle(float width, float height){ this.width=width; this.height=height; this.type=GeometricObject.RECTANGLE; } public float getSurface(){ return width*height; } } Java-Intensivkurs WS07/08 Folie 45 Abstrakte Klassen und Methoden class Triangle extends GeometricObject{ public float base; public float height; public Triangle(float base, float height){ this.base=base; this.height=height; this.type=GeometricObject.TRIANGLE; } public float getSurface(){ return .5f*base*height; } } Java-Intensivkurs WS07/08 Folie 46 Abstrakte Klassen und Methoden class Circle extends GeometricObject{ public float radius; public float getSurface(){ return (float)(Math.PI*radius*radius); } } Java-Intensivkurs WS07/08 Folie 47 Abstrakte Methoden Die Implementierung der Methode wird dann den Unterklassen überlassen Eine als abstract deklarierte Methode wird abstrakte Methode genannt Besteht sie nur aus einer Deklaration (nur Methodenkopf) Hat keinen Methodenrumpf (keine Implementierung) Anstelle der geschweiften Klammern des Methodenrumpfes wird ein Semikolon gesetzt //abstract method public abstract float getSurface(); Java-Intensivkurs WS07/08 Folie 48 Abstrakte Klassen Eine Klasse, die mindestens eine abstrakte Methode enthält, muss als abstract deklariert werden Abstrakte Klassen können nicht instanziiert werden Eine Unterklasse der abstrakten Klasse, erbt nun die abstrakten Methoden und muss diese überschreiben Tut sie das nicht, muss sie selbst als abstrakte Klasse definiert werden Eine abstrakte Klasse kann auch konkrete Methoden enthalten Java-Intensivkurs WS07/08 Folie 49