Kapitel 4: Klassen und Unterklassen

Werbung
Liste P: Programmieren mit Java
WS 2001/2002
Prof. Dr. V. Turau
FH Wiesbaden
Kapitel 4: Klassen und Unterklassen
Folie 54 : Unterklassen
Die Bildung von Unterklassen und das Konzept der Vererbung sind wichtige Prinzipien
objektorientierter Programmierung
Überschneidet sich die Funktionalität zweier Klassen, so werden die Gemeinsamkeiten nicht
mehrfach implementiert, sondern
eine Klasse wird als Unterklasse der anderen umgesetzt und erbt so die gemeinsame
Funktionalität
oder
die Gemeinsamkeiten werden in einer eigenen Klasse implementiert
die ursprünglichen Klassen werden als Unterklassen umgesetzt
Folie 55 : Klassenvereinbarung
Beispiele:
public class Tabelle extends Element { ... }
public abstract class Dialog extends Window { ... }
Folie 56 : Klassenhierarchie
Klassen sind in einer Hierarchie angeordnet
Jede Klasse außer Object hat genau eine Oberklasse
Keine Mehrfachvererbung
Wird bei der Klassenvereinbarung keine Oberklasse angegeben, so ist Object die Oberklasse
Eine Klasse erbt die sichtbaren Variablen und Methoden
Konstruktoren werden nicht vererbt
Folie 57 : Klassenvereinbarung (Beispiel)
In einer Anwendung sollen XHTML-Seiten generiert werden
Eine XHTML-Seite besteht aus Elementen (Tags)
Tags sind ineinander geschachtelt und können Attribute haben
Beispiele:
<img src=’cat.gif’ height=’700’/>
<ol> <li> Erstens </li> ...</ol>
Zur Repräsentation von XHTML-Elementen wird die Klasse Element erstellt
Folie 58 : Klassenvereinbarung (Beispiel)
Was muss dargestellt werden?
Name des Elementes
Unterelemente (Reihenfolge ist wichtig)
Attributenamen und ihre Werte (Reihenfolge ist nicht wichtig)
Welche Typen bzw. Klassen werden verwendet?
String
Vector
Properties
Folie 59 : Klassenvereinbarung (Beispiel)
Welche Funktionalität soll angeboten werden?
Elemente mit gegebenem Namen erzeugen
Unterelemente einfügen
Attribute hinzufügen
Eine textuelle Darstellung erzeugen
Folie 60 : Die Klasse Element
import java.io.*;
import java.util.*;
public class Element {
public static final int EINZUG = 2;
Vector unterElemente = new Vector();
Properties attribute = new Properties();
String name;
protected Element() {
}
public Element(String name) {
this.name = name;
}
public Element insertElement(Element e) {
unterElemente.add(e);
return this;
}
Folie 61 : Die Klasse Element (Forts.)
public Element addAttribut(String name, String wert) {
attribute.setProperty(name, wert);
return this;
}
public void println(PrintWriter w, int offset) {
printOffset(w, offset);
w.print(’<’ + name);
printAttribute(w);
if (unterElemente.size() == 0)
w.println("/>");
else {
w.println(">");
printUnterElemente(w, offset + EINZUG);
printOffset(w, offset);
w.println("</" + name + ’>’);
}
}
Folie 62 : Die Klasse Element (Forts.)
protected void printUnterElemente(
PrintWriter w, int offset){
Iterator elemente = unterElemente.iterator();
while (elemente.hasNext())
((Element)elemente.next()).println(w, offset);
}
protected void printAttribute(PrintWriter w) {
Enumeration enum = attribute.propertyNames();
while (enum.hasMoreElements()) {
String name = (String) enum.nextElement();
w.print(’ ’ + name + "=’" +
attribute.getProperty(name) + "’");
}
}
protected static void
printOffset(PrintWriter w, int off){
for (int i = 0; i < off; i++)
w.print(’ ’);
}
Folie 63 : Anwendung
Die Anweisungen
Element wurzel = new Element("html");
Element head = new Element("head");
Element body = new Element("body");
body.addAttribut("bgcolor", "blue");
wurzel.insertElement(head);
wurzel.insertElement(body);
wurzel.println(new PrintWriter(System.out), 0);
erzeugen folgende Ausgabe:
<html>
<head>
</head>
<body bgcolor=’blue’>
</body>
</html>
Folie 64 : Anwendung
Diese Anweisungen erzeugen die gleiche Ausgabe
Element wurzel = new Element("html");
wurzel.insertElement(new Element("head")).
insertElement(new Element("body").
addAttribut("bgcolor", "blue"));
wurzel.println(new PrintWriter(System.out), 0);
Hinweis: insertElement und addAttribut geben this zurück
Folie 65 : Die Klasse Img
Das Image-Tag: <img src=’java.gif’ alt=’Übersicht’/>
public class Img extends Element {
public Img(String src, String alt) {
super("img");
addAttribut("src", src);
addAttribut("alt", alt);
}
public Img(String src) {
this(src, "Ein Bild");
}
}
new Img("java.gif", "Übersicht")
Folie 66 : Überschreiben von Methoden
Hat die Methode einer Klasse die gleiche Signatur wie eine Methode in der Oberklasse, so wird
die Methode der Oberklasse in der Unterklasse überdeckt.
Overriding
Achtung Unterschied: Overloading -- Overriding
Eine überschriebene Methode kann einen anderen Modifier haben, allerdings darf der Zugriff nicht
eingeschränkt werden.
Folie 67 : Die Klasse Text
public class Text extends Element {
String text;
public Text(String text) {
this.text = text;
}
public void println(PrintWriter w, int offset) {
for (int i = 0; i < offset; i++)
w.print(’ ’);
w.println(text);
}
public Element insertElement(Element e) {
return this;
// Text kann keine Unterelemente haben
}
}
Folie 68 : Die Klasse A
Das A-Tag: <a href=’skrip.html’> Das Skript </a>
public class A extends Element {
public A(String href, String text) {
this(href, new Text(text));
}
public A(String href, Element e) {
super("a");
addAttribut("href", href);
insertElement(e);
}
}
new A("skrip.html", "Das Skript")
Folie 69 : Sichtbarkeit von Klassen
Variablen und Methoden einer Klasse nennt man zusammen Members (Achtung: lokale Variablen
von Methoden sind keine Members)
Die Sichbarkeit einer Klasse wird durch den Modifier public gekennzeichnet
Eine Klasse ohne den Modifier public ist nur im eigenen Paket sichtbar, public Klassen sind
überall sichtbar
Die Sichbarkeit der Members einer Klasse wird durch die Modifier public, protected und private
gekennzeichnet
Folie 70 : Sichtbarkeit von Members
public Members sind überall sichtbar
protected Members sind in Klassen des gleichen Paketes und in Unterklassen sichtbar (etwas
vereinfacht ausgedrückt)
Members ohne Modifier sind nur in Klassen des eigenen Paketes sichtbar
private Members sind außerhalb der Klasse nicht sichtbar
Folie 71 : Vererbung von Variablen
Eine Klasse erbt von ihrer direkten Oberklasse alle Klassen- und Instanzvariablen, welche
innerhalb der Klasse sichtbar sind und nicht durch lokale Vereinbarungen überdeckt werden.
Konsequenzen:
private Variablen werden nicht vererbt
an Klassen in anderen Paketen werden nur public und protected Variablen vererbt
Das Überdecken von Variablen sollte vermieden werden!
Folie 72 : Vererbung von Methoden
Eine Klasse erbt von ihrer direkten Oberklasse alle Klassen- und Instanzmethoden, welche
innerhalb der Klasse sichtbar sind und nicht durch lokale Vereinbarungen überdeckt werden.
Beispiel: Die Klasse Object vereinbart eine Methode toString(). Fast alle Klassen
überschreiben diese Methode und geben klassenspezifische Daten aus
In C++-Terminologie: alle Methoden sind virtuell, d.h. die Auswahl der ausgeführten Methode
erfolgt erst zur Laufzeit (late binding)
Folie 73 : Late Binding
public class A {
public String toString() {
return "Ich bin ein A";
}
}
public class B extends A {
public String toString() {
return "Ich bin ein B";
}
public static void main(String[] a) {
A a = new B(), b = new A();
System.out.println(a.toString());
System.out.println(b.toString());
}
}
Folie 74 : Late Binding
Ausgabe:
Ich bin ein B
Ich bin ein A
Besonderheit der Methode println:
Hat der übergebene Parameter nicht den Typ String, so wird automatisch die Methode
toString() an den Parameter geschickt und deren Rückgabe wird ausgegeben.
D.h. System.out.println(a.toString()) und System.out.println(a) bewirken die
gleiche Ausgabe
Folie 75 : Final Members
Das Schlüsselwort final kann bei der Vereinbarung von Klassen, Methoden und Variablen
angegeben werden:
Klassen: Es können keine Unterklassen gebildet werden (Beispiele: String, URL,
Integer)
Methoden: Dürfen nicht überschrieben werden
Variablen: Ein einmal zugewiesener Wert kann nicht mehr verändert werden.
In vielen Fällen kann der Compiler den Code optimieren
Folie 76 : Abstrakte Klassen und Methoden
Abstrakte Klassen können Methoden vereinbaren, ohne dafür eine Implementierung anzugeben
Solche Methoden werden genau wie abstrakte Klassen mit dem Modifier abstract
gekennzeichnet
Unterklassen von abstrakten Klassen
sind selber abstrakt oder
implementieren alle abstrakten Methoden der Oberklasse
Folie 77 : Abstrakte Klassen und Methoden
Von abstrakten Klassen können keine Instanzen gebildet werden
Anwendung: Abstrakte Klassen werden eingesetzt, wenn ein Teil der Funktionalität von der
speziellen Ausprägung eines Objektes abhängt, der andere Teil gilt für alle Ausprägungen und
kann mit Hilfe der abstrakten Methoden implementiert werden
Abstrakte Klassen können Konstruktoren vereinbaren, warum?
Folie 78 : Abstrakte Klassen und Methoden (Beispiel)
package java.awt.image;
public abstract class ColorModel {
public
public
public
public
abstract
abstract
abstract
abstract
int
int
int
int
getRed(int pixel);
getGreen(int pixel);
getBlue(int pixel);
getAlpha(int pixel);
public int getRGB(int pixel) {
return (getAlpha(pixel) << 24) |
(getRed(pixel) << 16) |
(getGreen(pixel) << 8) |
(getBlue(pixel) << 0) ;
}
}
Folie 79 : Native Methoden
Methoden einer Java-Klasse können auch in C implementiert werden
Solche Methoden haben den Modifier native
Zu Bindung der C-Programme an Java Klassen wird das Werkzeug javah verwendet
Nachteil von nativen Methoden: Plattformunabhängigkeit geht verloren
Anwendungsbeispiel: Kommunikation mit spezieller Hardware
Folie 80 : Garbage Collection
Java hat eine automatische Freispeicherverwaltung
Der Garbage Collector läuft in einem eigenen Thread und arbeitet im Hintergrund
Sobald ein Objekt nicht mehr über andere Objekte bzw. Variablen erreichbar ist, kann der belegte
Speicher vom Garbage Collector freigegeben werden
Die Option -verbose:gc des Java Interpreters zeigt die Aktivität des Garbage Collectors an
Herunterladen