 
                                Java
FH Merseburg SS 2002
String Übung:
Ziel:
 Zugriff auf die Stringkomponenten und Auswertung
 Zählen der Häufigkeit eines Buchstabens:
public class ZeichenZaehler
{
public static void main (String args[]) {
String str = new String ("Java ist eine
interessante Sprache.");
long zeichenZaehler[] = new long [256]; // 65536
for (int i = 0; i < str.length(); i++)
zeichenZaehler[str.charAt(i)] ++;
for (int i = 0; i < zeichenZaehler.length; i++)
if (zeichenZaehler[i] > 0)
System.out.println((char)(i) + "\t[" + i +
"]\t- " + zeichenZaehler[i] + " mal");
wait a = new wait();
a.waitForReturn();
}
}
481353149
.
J
S
a
c
e
h
i
n
p
r
s
t
v
[32] - 4 mal
[46] - 1 mal
[74] - 1 mal
[83] - 1 mal
[97] - 4 mal
[99] - 1 mal
[101] - 6 mal
[104] - 1 mal
[105] - 3 mal
[110] - 3 mal
[112] - 1 mal
[114] - 2 mal
[115] - 3 mal
[116] - 3 mal
[118] - 1 mal
Druecken Sie ENTER ...
-1-
Java
2.10
FH Merseburg SS 2002
Rückgabe von mehreren Werten
Rücklieferung von Werten einer Methode an die aufrufende Methode
 Rückgabewert ist ein Feld, das alle Werte desselben Objekttyps aufnimmt
 ein Objekt kann als Parameter übergeben werden, und dessen Daten werden
von der Methode geändert
 innerhalb der aufgerufenen Methode wird ein neues Objekt erzeugt, das die
Daten aufnimmt und als Rückgabewerte an die aufrufende Methode
zurückliefert
// Daten-Container zur Aufnahme verschiedener Attribute
// vergleichbar mit struct in C
class GeoFigDaten
{
public double laenge;
public double breite;
// z.B. 7.0
// z.B. 6.0
// Konstruktor
GeoFigDaten () {
this.laenge = 7.7;
this.breite = 6.6;
}
// Konstruktor
GeoFigDaten (double
this.laenge =
this.breite =
}
// mehrere Methoden
laenge, double breite) {
laenge;
breite;
zum setzen und lesen der Attribute
}
Bearbeitung der Daten in einer anderen Klasse
 Rückgabe mit Objekt der Containerklasse und
 Rückgabe ueber Parameter Objekt
// Klasse aendert die Daten im Datencontainer
class GFDAendern
{
// liefert die Daten ueber ein Rueckgabe Objekt zurueck
public GeoFigDaten GFDerstellen () {
GeoFigDaten neudaten = new GeoFigDaten();
// Benutzereingaben moeglich
neudaten.laenge = 8.0;
neudaten.breite = 9.0;
return neudaten;
}
// aendert Daten in Objekt, das als Parameter uebergeben wurde
public void GFDerstellen (GeoFigDaten x) {
// Benutzereingaben moeglich
x.laenge = 11.0;
x.breite = 12.0;
}
}
481353149
-2-
Java
FH Merseburg SS 2002
Benutzung des Datencontainers und der Methode in Main-Methode:
// Problem: Rueckgabe mehrerer Werte ueber eine "Daten-Klasse" GeoFigDaten:
class Control
{
public static void main (String args[]) {
// Erzeugen Instanz von GeoFigDaten (2 Konstruktoren)
// Ausgabe der Attribute aus GeoFigDaten
GeoFigDaten a = new GeoFigDaten(3.0,4.0);
System.out.println("Laenge: " + a.laenge);
System.out.println("Breite: " + a.breite);
// benutzen einer M. GFDAendern zum Veraendern der Attribute
// in GeoFigDaten mit Rueckgabe eines GeoFigDaten-Objektes
// zuweisen des Rueckgabe-Objektes an eine Instanz
GFDAendern b = new GFDAendern();
a =
b.GFDerstellen();
System.out.println("Laenge: " + a.laenge);
System.out.println("Breite: " + a.breite);
// ... waitForReturn();
}
}
Speicherverwaltung (automatisch) und Garbage Collection
 Speicherbereich wird in Java durch Laufzeitsystem überwacht
 in anderen Programmiersprachen durch Programmierer  z. B. Rückgabewert
von malloc
 Löschen von Objekten
 mit new  neues Objekt, aber kein delete
 in C durch Programmierer: malloc  free
 Konstruktoren, aber keine Destruktoren
 in Java durch Java - Laufzeitsystem organisiert  Garbage Collector gibt
Speicherplatz frei, wenn Objekt nicht mehr referenziert wird
 immer wenn neue Objekte erzeugt werden und nicht genügend Speicherplatz
zur Verfügung steht  Garbage Collector
 das Ende der Referenzierung eines Objektes ist erreicht,
 wenn keine statische Objektkomponente das Objekt referenziert oder
 wenn keine z. Z. ausgeführte Methode eine Referenz zum Objekt
besitzt (bei innerhalb der Methode erzeugten Referenzen wird diese
beim Verlassen der Methode aufgelöst)
a1
...
c1
A a1 ...
von anderen
Objekten
481353149
a2
...
b1
...
class A
...
class B
...
class C
...
-3-
Java
FH Merseburg SS 2002
 Java verwaltet die Anzahl der Referenzen auf ein Objekt
 sobald keine Referenzen auf ein Objekt existieren, wird es zur GC freigegeben
(siehe Referenz auf C  fehlt diese Referenz, dann Freigabe, danach auch
Freigabe für a1, a2, b1
Möglichkeiten der Löschung:
 belegen durch null
// = Objekt wird nicht mehr benutzt
Beispiel
public static void main (String args[]) {
int ergebnis, feld[] = new int[100];
init_feld(feld);
// Feld initialisieren
ergebnis = verarb_Feld(feld);
// und benutzen
// ab hier wird feld nicht mehr benötigt
feld = null;
// Rest des Programms
}
 Objekte können außer Speicher auch noch andere Ressourcen benutzen (Datei
Streams, Netzwerkverbindungen etc.)  GC darf diese Ressourcen nicht
eigenmächtig freigeben  daher ruft er vor der Freigabe die Methode
finalize() auf,
 diese kann je Objekt definiert werden und sollte die Ressourcen selbst
freigeben
public class DateiRessourcen {
private Stream File;
public DateiRessourcen (String pfad) {
File = new Stream (pfad);
}
// ... weitere Programmanweisungen
public void close ()
{
if (File != null) {
File.close();
File = null;
}
}
//Überschreibende Methode
// Methode von Stream
// in dieser Formulierung funktioniert close() auch bei
// mehrfachem Aufruf
protected void finalize() throws Throwable {
super.finalize(); // sollte immer so gemacht werden
// ansonsten ist eigene Klasse O.k.
// aber Oberklassen evtl. problematisch
close();
}
 kein Parameter und kein Rückgabewert
 Operationen können zu einem Fehler oder Ausnahmezustand führen 
 anstoßen einer Ausnahmebehandlung durch Throwable
 eigene Fehlerbehandlung durch try/catch
 Schlüsselwort throws gibt an, welche Ausnahmen eine Methode erzeugen
kann (throw = erzeugen von Exceptions)
 Klasse Throwable ist Oberklasse für alle Ausnahmeklassen
481353149
-4-
Java
FH Merseburg SS 2002
 endet eine Anwendung werden die finalize() Methoden aller Objekte
aufgerufen, wenn nicht ein Systemfehler (z. B. unzureichender Speicherplatz)
dies verhindert
 expliziter Aufruf des GC mit : System.gc();
Beispiel Geofigur:
public class GeoFigur
{
protected float Laenge;
protected float Breite;
protected float Flaeche;
static protected int InstZaehler;
// Konstruktor 1
public GeoFigur() {
++InstZaehler;
}
// Konstruktor 2
public GeoFigur(float x) {
Länge = x;
++InstZaehler;
}
// Konstruktor 3
public GeoFigur(float x, float y) {
Länge = x;
Breite = y;
++InstZaehler;
}
public void finalize() {
--InstZaehler;
}
// weitere Methoden zum Setzen und Lesen der Attribute
public abstract float berechneVolumen();
}
Abstrakte Klassen
Grundlage: Basisklasse kann keine Instanzen erzeugen
Ausgangspunkt war Vererbung – Übernahme von Attributen und Methoden in
abgeleitete Klassen
Beispiel Geofigur
public class GeoFigur
{
protected float Länge;
protected float Breite;
protected float Fläche;
static protected int InstCounter;
//
//
//
//
Konstruktoren, wie z. B.
public GeoFigur() {}
public GeoFigur(float x) {}
public GeoFigur(float x, float y) {
}
// public void finalize() {--InstCounter; }
481353149
-5-
Java
FH Merseburg SS 2002
// Methoden zum Setzen und Lesen
public float setl(float x) { }
public float getl() { }
public float setb(float y) { }
public float getb() {
}
diese Attribute und Methoden sind allgemeingültig,
andere Methoden machen nur für konkrete Instanz Sinn, wie beispielsweise:
public abstract float berechneFlaeche();
public abstract float berechneVolumen();
diese Methoden erhalten den Modifier abstract:
abstrakte Methoden können nicht vom Typ static private oder final
sein
sie enthalten keine Methodendefinition
beinhaltet eine Klasse eine abstrakte Methode, dann ist die Klasse
selbst abstrakt
Abstrakte Klassen sind durch das Schlüsselwort „abstract“ gekennzeichnet und
können nicht als final deklariert werden. Sie können auch nicht instanziert
werden.
Soll eine abstrakte Klasse verwendet werden (im Beispiel die Ableitungen
Dreieck, Rechteck, Kreis) muß die abstrakte Methode implementiert werden.
Allen abgeleiteteten Klassen sind aber die abstrakten Methoden gemeinsam
(gleiche Parameter und Rückgabewerte).
Schnittstellen / Interfaces
In manchen Fällen ist es sinnvoll, eine Klasse mit zwei oder mehr Basisklassen
zu erzeugen  Mehrfachvererbung
Beispiel Leichtathlet
Basisklasse: Leichtathlet
Abgeleitet:
Weitspringer – Hochspringer – 100m Läufer – Hürdenläufer ...
Neue Klasse:
Zehnkämpfer
Erbt von bestimmten Klassen, die von Leichtathlet abgeleitet sind 
Übernimmt M und A von 10 Klassen
Problem: sind in den Basisklassen Variablen oder Methoden mit gleichem
Namen aber unterschiedlicher Ausprägung vorhanden  Zuordnung schwierig
Beispiel: Weitspringer und Hochspringer könnten M springe() enthalten
Es muß aber konkret eine Methode angesprochen werden
Alternativen:
 Es könnte eine Methode fest angesprochen werden  aber Vorteile der
Mehrfachvererbung gehen verloren
 Bei jedem Aufruf eine M explizit angeben z.B. Weitspringer.springe()  auf
dynamische Zuordnung von M. wird verzichtet
481353149
-6-
Java
FH Merseburg SS 2002
Mehrfachvererbung wird aber nur in wenigen Fällen wirklich nutzbringend
eingesetzt
Zehnkämpfer ist weder Weitspringer noch Hochspringer
Interfaces
 Mit Schnittstellen überwindet Java die Einschränkungen der Einfachvererbung
ohne die Nachteile der MFV in Kauf nehmen zu müssen
 IF definieren beliebige Anz. Von Methoden und Variablen und damit
gleichzeitig eigenen Referenztyp
Um eine Schnittstelle S zu implementieren muß eine Klasse C alle in de
Schnittstelle enthaltenen Methoden konkret realisiseren  Verpflichtung
Schnittstelle kann andere Schnittstellen erweitern
Allgemeine Form:
[public] [abstract] interface InterfaceName [extends BasisInterface]
{
[public] [static] [final] Konstante1 = Wert1;
...
[public] [abstract] Methode1(Argumentliste);
}
Jede Variable in Interface gilt automatisch als static und final  es handelt sich
um eine Konstante die ist zu initialisieren
public interface Kalorien {
public double lesenKalorien();
}
Jede Klasse, die eine Methode lesenKalorien enthält, kann das Interface
implementieren:
public class SchokoKeks
extends Keks
implements Kalorien {
private double kal;
public double lesenKalorien() {
return kal;
}
// .. weitere Methoden von SchokoKeks
}
Andere Klassen können Referenzen auf Objekte der Klasse Interface erzeugen
und diesen Objekte der Klasse SchokoKeks zuweisen:
public class A {
Kalorien SKeks = new SchokoKeks();
System.out.println(Skeks.lesenKalorien());
...
}
Nutzen von Interfaces:
Wenn andere Klassen mit anderer Vererbungshierarchie ebenfalls das Interface
imlementieren
public class Pausenbrot
extends Brot
481353149
-7-
Java
FH Merseburg SS 2002
implements Kalorien {
...
public double lesenKalorien() {
... implementieren
}
}
Pausenbrot
und
Schokokeks
stammen
von
unterschiedlichen
Vererbungshierarchien, implementieren aber die gleiche Schnittstelle. Klasse A
kann daher über die Schnittstelle Kalorien die Methode lesenKalorien() aller
betreffender Klassen aufrufen:
public class A {
Kalorien SKeks = new SchokoKeks();
Kalorien PBrot = new Pausenbrot();
System.out.println(Skeks.lesenKalorien());
System.out.println(PBrot.lesenKalorien());
...
}
Packages
jede Klasse in eigener Datei  .class  Ziel der Packages: Gliederung der
Projektklassen und der Systembibliotheken
Pakete enthalten inhaltlich zusammengehörende Klassen, Schnittstellen und
Unterpakete. Alle Klassen gehören implizit zu einem Package, das unbenannt
ist.
spezielle Paketdeklaration:
package ein.paket.name;
class KlassenName {...}
der PaketName ist implizit jedem im Paket enthaltenen Typnamen
vorangestellt
vor allen Klassen und Schnittstellendefinitionen der Klasse
vollständiger Name für Package besteht aus Komponenten, die durch Punkte
getrennt sind
Korrespondez mit Verzeichnisstruktur (abhängig von Java-Implementation)
 Jede Komponente eines P-Namens kann einem bestimmten Verzeichnis des
Rechners zugeordnet werden
 Klassen und Schnittstellen werden als einzelne Dateien im Verzeichnis
gespeichert
Namenswahl:
 Grundsätzlich beliebig,
 systemweite Packages
 Namenskonvention von Sun  gewährleistet
weltweit eindeutige Namen für P.
 Internet Domain Namen + interner PackageName
Beispiele:
Package Klasse
481353149
zugehörige Dateinamen:
Meth
-8-
Java
FH Merseburg SS 2002
java.lang.Thread.start()
../java/lang/Thread.class
Package
Kl
Meth.
com.ms.awt.image.getsize()
../com/ms/awt/image.class
../lib/classes.zip
Package
Kl
DE.fh-fulda.informatik.pax.java.GeoFig.setB()
M
Pfadeinstellungen über CLASSPATH-Variable
Zugriff:
 über den direkten Namen einschließlich vorangestelltem Paketbezeichner
Klasse A in Package x.y.z  x.y.z.A
Eindeutige Referenz möglich:
public class B {
int f() {
x.y.z.A = einA;
x.y.z.A = nochEinA;
...
einA = new x.y.z.A();
}
}
Problem: unübersichtlicher Quelltext  import
Import x.y.z.A;
Import x.y.z.B;
public class D {
int g() {
A a =
B b =
new A();
new B();
x.y.z.C c = new x.y.z.C();
...
// nicht imp. Name
}
}
import von Teilen oder des ganzen Paketes
Import x.y.z.A;
Import x.y.z:*;
Importiert nur die Klassen einer Ebene  Unterpakete müssen selbst importiert
werden.
***
481353149
-9-