Files
tilman.de/www/uni/ws03/alp/java.php
T
2011-10-26 10:11:42 +02:00

235 lines
14 KiB
PHP

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
<link rel="stylesheet" type="text/css" media="all" href="stylesheet.css">
<title>Java</title>
</head>
<body>
<span id="menu"><a href="index.php">zurück zur Liste</a></span>
<div id="buttons">
<form action="edit.php" method="POST">
<input type="hidden" name="filename" value="<?php echo $_SERVER['SCRIPT_FILENAME']?>">
<p>
<input type="submit" value="Seite bearbeiten">
</p>
</form>
</div>
<h1>Java - Programmierparadigmen, Architekturprinzipien, Datenstrukturen &amp; Algorithmen</h1>
<small>Anm.:
<ol>
<li>Dass der geneigte Leser die Sprache Java auf ALP2-Niveau beherrscht, wird vorausgesetzt. Insofern lag die Schwierigkeit beim Schreiben haupsächlich in der Reduktion auf das Wesentliche, da man die Balance zwischen Verständlichkeit und Wiederholung von bekanntem finden musste. Also im Zweifel noch mal nachrecherchieren (s.a. <a href="#links">Links</a>) bzw. überspringen.
</li>
<li>
Da es in Java keine Funktionen, sondern nur Methoden (die auf Objekten arbeiten) gibt, werden die beiden Begriffe hier synonym verwendet.
</li>
</ol>
</small>
<h2><a name="objektorientierung"></a>Objektorientierung</h2>
<h3><a name="attribute"></a>Attribute &amp; Sichtbarkeit</h3>
<p>
<p>
Ein Bezeichner (eine Variable) <i>x</i> heißt <i>sichtbar</i> an einer Programmstelle, wenn er in einem der die Programmstelle umgebenden Blöcke vereinbart wurde. Man unterscheidet innerhalb von Klassen zwischen <i>globalen</i> und <i>lokalen</i> Variablen. Während globale Variablen innerhalb der ganzen Klasse gültig sind, haben lokale Variablen nur einen begrenzten Geltungsbereich (innerhalb ein Methode, Schleife oder eines Blocks).
</p>
<p>
Lokale Variablen verdecken globale, wenn sie denselben Bezeichner haben. D.h.: Existiert eine globale Variable <i>a</i> und definiert eine Methode erneut eine Variable <i>a</i>, so wird innerhalb der Methode durch den Bezeichner 'a' immer die lokale Variable angesprochen. Auf die globale Variable kann mithilfe des Schlüsselworts <span id="syntax">this</span> explizit zugegriffen werden.
</p>
<p>
Die Sichtbarkeit von Variablen kann durch die Attribute <span id="syntax">public</span>, <span id="syntax">private</span> und <span id="syntax">protected</span> beeinflusst werden:
<p>
<table border="1" style="empty-cells:hide; border-collapse:collapse;">
<tr>
<td><b>Sichtbarkeit</b></td><td>Innerhalb der Package</td><td>Abgeleitete Klassen</td><td>Außerhalb der Package</td>
</tr>
<tr>
<td>private</td><td>unsichtbar</td><td>unsichtbar</td><td>unsichtbar</td>
</tr>
<tr>
<td><i>default</i></td><td>sichtbar</td><td>unsichtbar</td><td>unsichtbar</td>
</tr>
<tr>
<td>protected</td><td>sichtbar</td><td>sichtbar</td><td>unsichtbar</td>
</tr>
<tr>
<td>public</td><td>sichtbar</td><td>sichtbar</td><td>sichtbar</td>
</tr>
</table>
</p>
Java-Klassen können entweder mit dem Attribut <span id="syntax">public</span> versehen werden (dann sind sie von überall erreichbar) oder Attributfrei sein. In diesem Fall haben sie <i>default</i>-Sichtbarkeit und können nur von Klassen aus derselben Package erreicht werden.
</p>
</p>
<p>
Beispiel:<br>
<pre>
package fahrzeuge;
public class Auto {
private int a = 1; /* a ist globale Variable in <i>Auto</i> und durch das Attribut
* <i>private</i> außerhalb der Klasse unsichtbar. Zuweisungen
* der Art myAuto.a = 5; sind nicht möglich. Die Variable
* wird nicht mitvererbt.
*/
public int b = 2; /* b ist globale Variable in <i>Auto</i> und durch das Attribut
* <i>public</i> von überall zu erreichen. Instanzen der Klasse
* akzeptieren Zuweisungen der Art myAuto.b = 8;
*/
protected int c = 3; /* c ist globale Variable in <i>Auto</i>. Durch das Attribut
* <i>protected</i> wird die Sichtbarkeit auf derselben package
* beschränkt. Die Variable wird an Ableitungen von Auto
* vererbt.
*/
public int getNumber(int x) {
int a = 4; /* a ist lokale Variable in getNumber() und verdeckt
* innerhalb von getNumber() die globale Variable a
*/
if (x < 10) return a; // Gibt 4 zurück
if (x > 20) return b; // Gibt 2 zurück. (Die globale Variable ist
// überall in Auto gültig
return this.a; // Gibt 1 aus. (durch das Schlüsselwort
// this wird die globale Variable a
// angesprochen
}
private String getPolicy() {
return ("Diese Methode kann nur innerhalb von Auto verwendet werden. " +
"Sie wird nicht mitvererbt.");
}
protected String getLiberalPolicy() {
return ("Diese Methode kann innerhalb von Auto und von allen Klassen aus " +
"der Package <i>fahrzeuge</i> verwendet werden. " +
"Sie wird an abgeleitete Klassen vererbt.");
}
}
</pre>
</p>
<p>
Weitere Atribute in Java sind <span id="syntax">static</span>, <span id="syntax">final</span> und die (eher speziellen und daher hier nicht näher beschriebenen) Attribute <span id="syntax">transient</span> und <span id="syntax">volatile</span>.<br>
<p>
<span id="syntax"><b>static</b></span><br>
Das Schlüsselwort <span id="syntax">static</span> ist auf Variablen und Methoden anwendbar. Ist eine Variable oder Methode mit dem Attribut <span id="syntax">static</span> belegt, so existiert sie für sämtliche Instanzen der Klasse zuammen nur einmal. Statische Variablen sind sogenannte Klassenvariablen. Ändert eine Klasse eine statische Variable, so ist sie auch für alle anderen Instanzen geändert.<br>
Da statische Variablen und Methoden keiner bestimmten Instanz angehören, können sie auch direkt über den Klassennamen erreicht werden, ohne dass erst eine Instanz der Klasse erstellt werden müsste.<br>
</p>
<p>
<span id="syntax"><b>final</b></span><br>
Das Schlüsselwort <span id="syntax">final</span> ist auf Variablen, Methoden und Klassen anwendbar.
<ul>
<li>
Finale Variablen müssen initialisiert werden und können zur Laufzeit nicht mehr verändert werden. (Sie ersetzen damit die in anderen Sprachen üblichen Konstanten.)
</li>
<li>
Finale Methoden können von abgeleiteten Klassen nicht überschrieben werden.
</li>
<li>
Finale Klassen können nicht abgeleitet werden, sie beenden die Vererbungskette und können nicht mehr erweitert werden.
</li>
</ul>
Da Elemente, die mit dem Attribut <span id="syntax">final</span> nicht änderbar sind, kann die Virtual Machine zur Laufzeit auf erneutes Laden von Variablen bzw. auf dynamische Methodensuche verzichten, weshalb finale Elemente oft deutlich performanter bearbeitet werden können.
</p>
</p>
<h3><a name="geheimnisprinzip"></a>Geheimnisprinzip</h3>
<p>
([<i>principle of</i>] <i>information hiding</i>) bezeichnet nach [Parnas '72] ein Entwurfsprinzip für Module. Module sollen ihre konkrete Implementierung verbergen. (&quot;Jedes Modul hat ein Geheimnis!&quot;)<br>Komponenten eines Softwaresystems werden als Black Boxes betrachtet, die nur relevante Informationen nach außen zeigen. In Java wird das Geheimnisprinzip insbesondere über Interfaces sowie die Attribute <span id="syntax">private</span> und <span id="syntax">protected</span> realisiert.<br>
Vorteile liegen in der konsequenten Modularisierung: Austauschbarkeit der Implementierung einer Klasse (bei Beibehaltung des Interfaces).<br>
Das Geheimnisprinzip ist auch für &rarr; Abstrakte Datentypen von Bedeutung.
</p>
<h3><a name="polymorphie"></a>Polymorphie</h3>
<p>
Polymorphie (lat. für Vielgestaltigkeit) bezeichnet Eigenschaft einer Variablen, für Objekte verschiedener Klassen stehen zu können. Es gibt verschiedene Arten von Polymorphie:<br>
<ul>
<li>
<b>Universelle Polymorphie</b><br>
Universell polymorphe Funktionen bearbeiten Objekte mit ähnlichen Eigenschaften auf dieselbe Weise. Man unterschiedet zwischen Inklusionspolymorphie und parametrischer Polymorphie:
<ul>
<li>
<b>Inklusionspolymorphie (Vererbung)</b> - eine Instanzvariable kann auch Objekte von Unterklassen aufnehmen. So kann eine Variable vom Typ <i>Motorrad</i> außer Motorrad-Objekten, auch solche vom Typ <i>Suzuki</i> oder <i>HarleyDavidson</i> aufnehmen.
</li>
<li>
<b>Parametrische Polymorphie (Typvariablen)</b> - eine Methode akzeptiert Parameter allgemeinen Typs (<i>Generizität</i>). In Java wird dies durch Methoden, die als Parameter den Typ <i>Object</i> akzeptieren realisiert. (Was ja eigentlich Inklusionspolymorphie ist - mal sehen was mit Java 1.5 kommt...) In Haskell gibt es den allgemeinen Parameter <i>a</i>.
</li>
</ul>
</li>
<li>
<b>Ad hoc Polymorphie (Überladen)</b><br>
Bei der Ad-hoc-Polymorphie, liegt den verschiedenen Parametern keine gemeinsame Struktur zugrunde. Die verschiedenen Typen werden unterschiedlich behandelt. Man erreicht dies durch <i>Überladen</i> von Methoden: Eine Methode kann mehrfach für verschiedene Parameter existieren.
</li>
</ul>
</p>
<h3><a name="assertions"></a>Assertions</h3>
<p>
Assertions (Zusicherungen) dienen zur Überprüfung von Invarianten, um Programme robuster zu machen. Dazu wird das Programm mit dem Schlüsslwort <span id="syntax">assert</span> (ab Java 1.4) angewiesen, eine Bedingung auf Wahrheit zu überprüfen. Trifft diese (i.d.R. wider Erwarten) nicht zu, wird eine Exception ausgelöst. Der Compiler kann über Parameter angewiesen werden, die Zusicherungen an- oder abzustellen, so dass diese z.B. nur während der Entwicklung genutzt werden und für die endgültige Fassung eines Programms zur Laufzeitoptimierung wegfallen.
</p>
<h3><a name="call-by"></a>Parameterübergabe: Call by value vs. Call by reference</h3>
<h4>Call by value</h4>
<p>
Der Parameter einer Methode entspricht eriner lokalen Variable, die bei Aufruf mit dem übergebenen Wert initialisiert wird (Parameter-Kopie). Ändert eine Methode den Parameter, so betrifft dies nur ihre lokale Kopie, nicht die übergebene Variable. In Java werden alle primitiven Datentypen per Call by value übergeben.
</p>
<h4>Call by reference</h4>
<p>
Paramter werden als Verweis auf eine Variable übergeben. Ändert eine Methode den Parameter, so ist auch die übergebene Variable geändert. In Java werden Objekte als Zeiger übergeben, so dass Änderungen immer global gelten.
</p>
<h4>Call by result</h4>
<p>
(Teilw. auch <i>call-by-value-return</i>, u.a. auch bei Schweppe.) Hier wird zunächst das Ergebnis berechnet, und dann in Parameter-Variablen zurückgegeben.
</p>
<p>
Beispiel (<b>kein Java!</b>):
<pre>
void solve(in float p, in float q, out float x1, out float x2)
{
float root = sqrt(p*p/4 - q);
x1 = -p/2 + root;
x2 = -p/2 - root;
}
</pre>
</p>
<h4>Call by name</h4>
<p>
Entspricht <i>lazy evaluation</i> wie z.B. in Haskell. Vom Ergebnis so wie <i>Call by reference</i>, allerdings mit anderer Semantik: Der übergebene <i>Bezeichner</i> ersetzt beim Aufruf den Parameter der Methodendeklaration, also so ähnlich wie Makros in C. So eine Art automatisches Copy'n'Paste. Die Sprache ALGOL verwendet dieses System, das bei modernen Sprachen kaum noch Anwendung findet. (s.a. <a href="http://foldoc.doc.ic.ac.uk/foldoc/foldoc.cgi?call-by-name">FOLDOC: call-by-name</a>)
</p>
<h2><a name="entwurfsmuster"></a>Entwurfsmuster</h2>
<p>
Entwurfsmuster (engl. <i>Design Patterns</i>) sind - in der Softwaretechnik - Lösungen für häufig auftretende Problemtypen im Programmdesign. Durch die Verwendung von Entwurfsmustern soll der Code robuster, eleganter und schneller werden, da man das Rad nicht immer neu erfindet, sondern stattdessen erprobte Lösungen verwendet. (Das Problem liegt also eher darin, die passende Lösung aus den bekannten herauszusuchen.)<br>
</p>
<h3>Häufig verwendete Entwurfsmuster</h3>
<ul>
<li>Singleton - Eine Klasse, von der nur eine Instanz erzeugt werden kann</li>
<li>Immutable - Eine Klasse, die nach der Initialisierung nicht mehr veränderbar ist</li>
<li>Interface - Trennt Eigenschaften von der Implementierung</li>
<li>Iterator - Durchläuft alle Elemente eine Collection</li>
<li>Factory - Übernimmt die Initialisierung und Instanziierung von verschiedenen Klassen mit gemeinsamen Eigenschaften</li>
</ul>
<h2><a name="datenstrukturen"></a>Datenstrukturen &amp; Implementierungen</h2>
<p>
</p>
<h2><a name="links"></a>Links</h2>
<p>
<a href="http://www.galileocomputing.de/openbook/javainsel2/">Java ist auch eine Insel</a><br>
<a href="http://www.dockter-its.de/jthemen/">Bemerkungen zu den (derzeitigen) Defiziten, z.B. Generics</a>
</p>
</body>
</html>