Algorithmen und Datenstrukturen - ReadingSample - Beck-Shop

Werbung
Algorithmen und Datenstrukturen
Eine Einführung mit Java
Bearbeitet von
Gunter Saake, Kai U Sattler
überarbeitet 2006. Buch. XVIII, 512 S. Hardcover
ISBN 978 3 89864 385 6
Format (B x L): 16,5 x 24 cm
Gewicht: 988 g
Weitere Fachgebiete > EDV, Informatik > Datenbanken, Informationssicherheit,
Geschäftssoftware > Zeichen- und Zahlendarstellungen
Zu Inhaltsverzeichnis
schnell und portofrei erhältlich bei
Die Online-Fachbuchhandlung beck-shop.de ist spezialisiert auf Fachbücher, insbesondere Recht, Steuern und Wirtschaft.
Im Sortiment finden Sie alle Medien (Bücher, Zeitschriften, CDs, eBooks, etc.) aller Verlage. Ergänzt wird das Programm
durch Services wie Neuerscheinungsdienst oder Zusammenstellungen von Büchern zu Sonderpreisen. Der Shop führt mehr
als 8 Millionen Produkte.
Teil I
Grundlegende Konzepte
3
1
Vorbemerkungen und Überblick
Im beginnenden neuen Jahrtausend ist es eigentlich nicht mehr notwendig, Begriffe wie Computer, Programm oder Software einzuführen.
Wir werden in diesem Kapitel trotzdem einige Vorbemerkungen machen, um den Kontext dieses Buches und der behandelten Begriffe zu
verdeutlichen.
1.1
Informatik, Algorithmen und
Datenstrukturen
Informatik ist ein Kunstwort aus den 60er Jahren, das die Assoziationen Informatik gleich Information oder Technik oder Informatik
gleich Information und Mathematik erwecken sollte. Bei der Begriffsbildung sollte durchaus bewusst ein Gegensatz zum amerikanischen Begriff Computer Science aufgebaut werden, um zu verdeutlichen, dass
die Wissenschaft Informatik nicht nur auf Computer beschränkt ist.
Informatik als Begriff ist insbesondere im nicht englischsprachigen europäischen Raum gebräuchlich. Die Informatik hat zentral zu tun mit
Informatik
❏ systematischer Verarbeitung von Informationen und
❏ Maschinen, die diese Verarbeitung automatisch leisten.
Wichtige Grundkonzepte der Informatik können in einer maschinenunabhängigen Darstellung vermittelt werden. Der Bezug zu den Themen
diese Buches kann durch die folgende Aussage hergestellt werden:
Die »systematische Verarbeitung« wird durch den Begriff Algorithmus präzisiert, Information durch den Begriff Daten.
In einer ersten Näherung kann man das Konzept des Algorithmus wie
folgt charakterisieren:
Ein Algorithmus ist eine eindeutige Beschreibung eines in mehreren Schritten durchgeführten (Bearbeitungs-)Vorganges.
Algorithmen und
Daten
4
1 Vorbemerkungen und Überblick
In der Informatik werden nun speziell Berechnungsvorgänge statt allgemeiner Bearbeitungsvorgänge betrachtet, wobei der Schwerpunkt auf
der Ausführbarkeit durch (abstrakte) Maschinen liegt, die auch als Prozessoren bezeichnet werden:
Prozessor
Ausdrucksfähigkeit
verschiedener
Notationen
Korrektheit und
Zeitbedarf
Datenstrukturen
Ein Prozessor führt einen Prozess (Arbeitsvorgang) auf Basis
einer eindeutig interpretierbaren Beschreibung (dem Algorithmus) aus.
In diesem Buch werden eine Reihe von Fragestellungen behandelt, die
Aspekte des Umgangs mit Algorithmen betreffen. Die verschiedenen
Notationen für die Beschreibung von Algorithmen führen direkt zu
Sprachkonzepten moderner Programmiersprachen.
Wenn verschiedene Notationen verwendet werden können, stellt
sich die Frage der Ausdrucksfähigkeit dieser Algorithmensprachen.
Man kann sich diese Fragestellungen daran verdeutlichen, dass man
sich überlegt, wie ausdrucksfähig die Bienensprache, die ja konkrete
Wegbeschreibungen ermöglicht, im Vergleich zu einer Programmiersprache zur Wegfindungsprogrammierung von Robotern ist, oder ob
dressierte Hunde tatsächlich dieselbe Sprache verstehen wie Menschen.
Spätestens beim Übergang zu konkreten Programmen in einer Programmiersprache müssen natürlich die Fragestellungen der Korrektheit
und des Zeitbedarfs bzw. der Geschwindigkeit von Programmen betrachtet werden.
In diesem Buch geht es primär um Algorithmen für Rechner, also
schnelle (aber dumme) Prozessoren (ein Rechner ist im Vergleich zu einem Menschen ein »Hochgeschwindigkeitstrottel«, der falsche Anweisungen prinzipiell nicht erkennen kann, aber sehr schnell als Programm
vorgegebene Anweisungen ausführen kann). Hierzu werden mathematisch formale Grundlagen von Algorithmen eingeführt – ein Rechner
»versteht« nur Bits, so dass jede Anweisungssprache auf diese einfache Ebene heruntergebrochen werden muss. Die Umsetzung von menschenverständlichen Algorithmen in eine maschinennahe Darstellung
geht natürlich nur, wenn die Bedeutung beider Darstellungen exakt formal festgelegt ist.
Auch wenn sich beim Programmieren scheinbar alles um die Algorithmen dreht, ist das Gegenstück, die Datenstrukturen, ebenfalls
ein zentraler Aspekt der Grundlagen der Informatik. Erst rechnerverarbeitbare Darstellungen von Informationen erlauben das Programmieren
realistischer Probleme auf einer angemessenen Abstraktionsebene – die
Zeit, in der ein Programmierer sich an den Rechner anpassen und direkt in Bits und Bytes denken musste, ist zumindest in der nicht stark
hardwarenahen Programmierung vorbei.
1.2 Historischer Überblick: Algorithmen
1.2
Historischer Überblick: Algorithmen
Die in diesem Buch behandelten Konzepte der Informatik sind älter als
die Geschichte der Computer, die Programme ausführen können. Die
Informatik behandelt Konzepte, die auch ohne existierende Computer gültig sind – aber zugegebenermaßen erst durch den Siegeszug der
Computer die heutige praktische Relevanz erlangten.
In diesem Abschnitt wollen wir kurz einige Ergebnisse aus der Zeit
vor dem Bau des ersten Computers nennen, um dies zu verdeutlichen:
300 v. Chr.: Euklids Algorithmus zur Bestimmung des ggT (beschrieben im 7. Buch der Elemente), also des größten gemeinsamen Teilers, mit dem etwa
ggT(300, 200) = 100
sehr effizient berechnet werden kann, ist die erste Beschreibung eines Verfahrens, das modernen Kriterien für Algorithmen gerecht
wird.
800 n. Chr.: Der persisch-arabische Mathematiker Muhammed ibn
Musa abu Djafar alChoresmi (oft auch als »al Chworesmi« oder
»al Charismi« geschrieben) veröffentlicht eine Aufgabensammlung für Kaufleute und Testamentsvollstrecker, die später ins Lateinische als Liber Algorithmi übersetzt wird.
Das Wort Algorithmus ist ein Kunstwort aus dem Namen dieses
Mathematikers und dem griechischen »arithmos« für Zahl.
1574: Adam Rieses Rechenbuch verbreitet mathematische Algorithmen in Deutschland.
1614: Die ersten Logarithmentafeln werden algorithmisch berechnet
– ohne Computer dauerte dies 30 Jahre!
1703: Binäre Zahlensysteme werden von Leibnitz eingeführt. Diese
Zahlensysteme bilden die Grundlage der internen Verarbeitung
in modernen Computern.
1815: Augusta Ada Lovelace, die erste »Computer-Pionierin«, wird geboren. Sie entwickelt schon früh Konstruktionspläne für verschiedenartige Maschinen, wird Assistentin von Babbage und entwirft
Programme für dessen erste Rechenmaschinen.
1822: Charles Babbage entwickelt die so genannte Difference Engine,
die in einer verbesserten Version 1833 fertig gestellt wird. Später
entwickelt er auch die Analytical Engine, die bereits die wichtigsten Komponenten eines Computers umfasst, aber niemals vollendet wird.
1931: Gödels Unvollständigkeitssatz beendet den Traum vieler damaliger Mathematiker, die gesamte Beweisführung aller Sätze in der
5
6
1 Vorbemerkungen und Überblick
Mathematik mit algorithmisch konstruierten Beweisen durchzuführen.
1936: Die Church’sche These vereinheitlicht die Welt der Sprachen zur
Notation von Algorithmen, indem für viele der damaligen Notationen die gleiche Ausdrucksfähigkeit postuliert wird.
danach: Mit der Realisierung der ersten Computer erfolgte natürlich
der Ausbau der Algorithmentheorie zu einem eigenen Wissenschaftsgebiet.
Auch für den Bereich der Datenstrukturen können lang zurückreichende Wurzeln gefunden werden, etwa das Indexierungssystem historischer
Bibliotheken.
Ein historischer Überblick, der auch die technische Informatik,
die Programmierung und Aspekte des Software Engineering behandelt,
würde den Rahmen des vorliegenden Buches sprengen. So werden wir
nur noch im folgenden Abschnitt, der die Wahl der Sprache Java als
Ausbildungssprache motivieren soll, die Historie der Programmiersprachen kurz anreißen.
1.3
Autocode
Fortran
Algol
Lisp
COBOL
Pascal
Historie von Programmiersprachen und
Java
Bevor wir näher auf die in diesem Buch verwendete Programmiersprache Java eingehen, lohnt es sich, einen Blick in die Geschichte zu werfen. Die Ursprünge höherer Programmiersprachen reichen zurück an
den Anfang der fünfziger Jahre, als erste Sprachen wie Autocode vorgeschlagen wurden, die bereits arithmetische Ausdrücke, Schleifen, bedingte Sprünge und Prozeduren umfassten. Daraus wurde dann Fortran (FORmula TRANslator) entwickelt, deren erste Fassung 1954 vorgestellt wurde und die auch heute noch speziell im wissenschaftlichtechnischen Bereich zum Einsatz kommt. Anfang der sechziger Jahre
wurden dann Algol (ALGOrithmic Language), eine Sprache, die u.a.
Pascal nachhaltig beeinflusst hat, Lisp, als die Grundlage aller funktionalen Programmiersprachen und im Bereich der künstlichen Intelligenz immer noch häufig eingesetzt, und die vielleicht noch am weitesten
verbreitete Programmiersprache COBOL (COmmon Business Oriented Language) entwickelt. Auch die Entwicklung von BASIC geht auf
die Mitte der sechziger Jahre zurück.
Die Methode der strukturierten Programmierung wurde wesentlich
durch Pascal begründet, eine Entwicklung von Niklaus Wirth zu Beginn der siebziger Jahre. Mit Pascal wurden nicht nur Sprachmittel eingeführt, die heute in allen modernen Programmiersprachen zu finden
1.3 Historie von Programmiersprachen und Java
7
sind, sondern es wurde auch erstmals die Programmausführung durch
die Interpretation von Zwischencode (so genannten P-Code) verwirklicht. Dieses Verfahren wurde dann bespielsweise für Java »wiederentdeckt« und hat wesentlich zur Verbreitung der Sprache beigetragen.
Ebenfalls Anfang der siebziger Jahre wurde ausgehend von Sprachen wie CPL und BCPL die Programmiersprache C entwickelt und
zur Implementierung des Betriebssystems UNIX eingesetzt. Damit wurde erstmals eine höhere Programmiersprache für die Betriebssystementwicklung verwendet. Der sich daraus ergebenden weitgehenden Maschinenunabhängigkeit ist es letztendlich zu verdanken, dass UNIX und
die Vielzahl der Derivate (wie u.a. Linux) heute auf nahezu allen Hardwareplattformen zu finden sind.
Die Idee modularer Programmiersprachen wurde ab Mitte der siebziger Jahre wiederum von Wirth mit Modula entwickelt und speziell
auch in Ada umgesetzt.
Objektorientierte Programmiersprachen wie Smalltalk, C++ oder
Java haben ihren Ursprung in Simula-67, die um 1967 in Norwegen als eine Sprache für die ereignisorientierte Simulation entstanden
ist. Das Potenzial objektorientierter Programmierung wurde zu dieser
Zeit jedoch noch nicht wirklich erkannt. Erst mit der Entwicklung von
Smalltalk durch Xerox PARC Ende der siebziger Jahre fanden Konzepte
wie »Klasse« oder «Vererbung« Einzug in die Programmierung. Ausgehend vom objektorientierten Paradigma einerseits und der Systemprogrammiersprache C andererseits wurde 1983 bei AT&T die Programmiersprache C++ entworfen, die nicht zuletzt wegen der »Abwärtskompatibilität« zu C schnell eine weite Verbreitung fand.
Als Entwicklungen der letzten Jahre vor Java sind insbesondere
Eiffel von Bertrand Meyer mit dem neuen Konzept der Zusicherungen bzw. des vertraglichen Entwurfs (design by contract), Oberon von
Wirth mit dem Ziel einer Rückbesinnung auf einen einfachen, kompakten und klaren Sprachentwurf sowie die Vielzahl von Skriptsprachen
wie Perl, Tcl oder Python zu nennen.
Die Arbeiten zu Java lassen sich bis in das Jahr 1990 zurückverfolgen, als bei Sun Microsystems eine Sprache für den ConsumerElectronics-Bereich unter dem Namen Oak entwickelt werden sollte.
Entwurfsziele dieser Sprache waren bereits Plattformunabhängigkeit
durch Verwendung von Zwischencode und dessen interpretative Ausführung, Objektorientierung und die Anlehnung an C/C++, um so den
Lernaufwand für Kenner dieser Sprachen gering zu halten. Mit der Entwicklung des World Wide Web um 1993 fand im Entwicklerteam eine
Umorientierung auf Web-Anwendungen und damit eine Umbenennung
in Java – die bevorzugte Kaffeesorte der Entwickler – statt.
C
Modula
Simula-67
Smalltalk
C++
Eiffel
Java
8
1 Vorbemerkungen und Überblick
HotJava
Netscape
Java Development
Kit
J2SE 5.0
1995 wurde die Sprache dann zusammen mit einer Referenzimplementierung und dem HotJava-Browser der Öffentlichkeit vorgestellt.
Dieser Browser ermöglichte erstmals aktive Web-Inhalte – durch so
genannte Applets. Hinter diesem Begriff verbergen sich kleine JavaProgramme, die als Teil eines Web-Dokumentes von einem Server geladen und in einem geschützten Bereich des Browsers ausgeführt werden können. Da der HotJava-Browser selbst in Java geschrieben wurde,
war dies gleichzeitig die Demonstration der Eignung von Java für größere Projekte. Als Netscape – damals unbestrittener Marktführer bei
Web-Browsern – kurz darauf die Unterstützung von Java-Applets in
der nächsten Version des Navigators bekannt gab, fand Java in kürzester Zeit eine enorme Verbreitung. Dies wurde auch noch dadurch
verstärkt, dass die Entwicklungsumgebung für Java von Sun kostenlos
über das Web zur Verfügung gestellt wurde. Im Jahre 1997 wurde dann
die Version 1.1 des Java Development Kit (JDK) freigegeben und alle
großen Softwarefirmen wie IBM, Oracle oder Microsoft erklärten ihre
Unterstützung der Java-Plattform. Mit der Veröffentlichung von Java 2
im Jahr 1998 und der Folgeversionen des JDK hat sich dann nicht nur
die Anzahl der Systemplattformen, auf denen Java-Programme lauffähig sind, vergrößert, sondern insbesondere auch die Zahl der Klassenbibliotheken, die für Java verfügbar sind. In der aktuellen, im Sommer
2005 freigegebenen Version J2SE 5.0 (Java 2 Platform Standard Edition) wurden schließlich auch einige neue Sprachkonzepte eingeführt,
auf die wir an geeigneter Stelle eingehen werden.
Geblieben sind die ursprünglichen Ansprüche: eine leicht erlernbare, klare und kompakte Sprache, die die Komplexität beispielsweise
von C++ vermeidet, aber dennoch das objektorientierte Paradigma umsetzt. Gleichzeitig ist Java architekturneutral, d.h., durch Verwendung
eines plattformunabhängigen Zwischencodes sind Programme auch in
kompilierter Form portabel – eine Eigenschaft, die für eine moderne
Internet-Programmiersprache fundamental ist.
1.4
Programm
Grundkonzepte der Programmierung in
Java
Ein fundamentaler Begriff beim Programmieren – eigentlich beim Umgang mit Computern allgemein – ist das Programm. Egal ob man ein
Textverarbeitungssystem oder ein kleines, selbst geschriebenes JavaProgramm zur Berechnung der Fakultät einer Zahl betrachtet – in bei-
1.4 Grundkonzepte der Programmierung in Java
9
den Fällen handelt es sich um ein Programm (oder eine Sammlung davon).
Ein Programm ist die Formulierung eines Algorithmus und der zugehörigen Datenstrukturen in einer Programmiersprache.
2
Definition 1.1
Programm
Die Grundbausteine von Programmen in höheren Programmiersprachen werden wir erst in den nächsten Kapiteln kennen lernen.
Intuitiv wissen wir aber, dass zumindest Anweisungen wie elementare
Operationen, bedingte Anweisungen und Schleifen, Datentypen zur
Festlegung der Struktur der Daten und darauf definierte Operationen
sowie die Möglichkeit der Formulierung von Ausdrücken benötigt
werden.
Die syntaktisch korrekte Kombination dieser Bausteine allein führt
jedoch noch nicht zu einem ausführbaren Programm. Da Programme
meist in einer für Menschen schreib- und lesbaren Form erstellt werden, sind sie für Computer, die nur einen von der jeweiligen Prozessorarchitektur (etwa Intels x86-Familie, die SPARC-Prozessoren von Sun
oder die PowerPC-Prozessorfamilie der Macs bzw. IBM-Rechner) abhängigen Maschinencode »verstehen«, nicht direkt ausführbar. Es ist
daher eine Übersetzung oder auch Kompilierung (engl. compile) des
Programms aus der Programmiersprache in den Maschinencode notwendig. Die Übersetzung erfolgt durch ein spezielles Programm, das als
Compiler bezeichnet wird. Neben der Übersetzung in Maschinencode
führt einer solcher Compiler auch noch verschiedene Überprüfungen
des Programms durch, z.B. ob das Programm hinsichtlich der Syntax
korrekt ist, ob benutzte Variablen und Prozeduren deklariert sind u.Ä.
Programmiersprachen wie C, C++ oder (Turbo-)Pascal basieren auf diesem Prinzip.
Da jede Änderung am Programmtext eine Neukompilierung erfordert, verzichtet man bei einigen Sprachen auf die Übersetzung, indem
die Programme interpretiert werden. Das bedeutet, dass ein spezielles
Programm – der so genannte Interpreter – den Programmtext schrittweise analysiert und ausführt. Der Interpreter muss also Syntax und
Semantik der Sprache kennen! Der Vorteil dieses Ansatzes ist, dass die
Kompilierung entfällt und dadurch Änderungen vereinfacht werden.
Auch ist das Programm (man spricht häufig auch von Skripten) unabhängig von einer konkreten Prozessorarchitektur. Diese Vorteile werden
durch die Notwendigkeit eines Interpreters und eine durch die interpretierte Ausführung verschlechterte Performance erkauft. Beispiele für
Sprachen, die mit diesem Prinzip realisiert werden, sind insbesondere
die im Web-Umfeld beliebten Skriptsprachen wie JavaScript.
Compiler
Interpreter
Skriptsprachen
10
1 Vorbemerkungen und Überblick
Bytecode
Abbildung 1.1
Compiler und
Interpreter bei Java
Java basiert auf einem kombinierten Ansatz (Abbildung 1.1). Programme werden zwar kompiliert, jedoch nicht in einen prozessorspezifischen Maschinencode, sondern in einen so genannten Bytecode.
Hierbei handelt sich um Code für eine abstrakte Stack-Maschine. Dieser Bytecode wird schließlich von einem Java-Interpreter, der virtuellen Java-Maschine (Java VM – engl. Virtual Machine), ausgeführt. Da
der Bytecode relativ maschinennah ist, bleibt die Interpretation und
Ausführung einfach, wodurch der Performance-Verlust gering gehalten
werden kann. Andererseits lassen sich auf diese Weise auch übersetzte
Java-Programme auf unterschiedlichen Prozessorarchitekturen ausführen, sofern dort eine Java-VM verfügbar ist.
class A {
int a, b, c;
void add () {
} .java
}
Java-Compiler
0010010
0100101
1001011
.class
Java-VM
Klassenbibliothek
Aufbau von
Java-Programmen
Klasse
Methoden
main-Methode
Wie ist nun ein Java-Programm aufgebaut? Ein solches Programm
besteht aus einer oder mehreren Klassen, die damit das Hauptstrukturierungsmittel in Java darstellen. Wir werden auf den Begriff der Klasse
später im Zusammenhang mit Datenstrukturen noch genauer eingehen.
Zunächst wollen wir darunter nur ein Modul verstehen, das eine Menge von Variablen und Prozeduren bzw. Funktionen kapselt. Im Sprachgebrauch von Java werden Prozeduren und Funktionen, d.h. die Zusammenfassung von Anweisungen zu einer logischen Einheit, auch als
Methoden bezeichnet.
Abbildung 1.2 verdeutlicht den Aufbau eines Java-Programms aus
mehreren Klassen. Jede Klasse ist durch einen Namen gekennzeichnet
und kann Attribute und Methoden definieren. Mindestens eine Klasse
muss eine spezielle Methode main besitzen, die den Einstiegspunkt für
die Ausführung bildet. Wenn das Programm später ausgeführt werden
soll, ist der Name der Klasse mit der main-Methode (engl. für »Haupt«Methode) anzugeben. Beim Start wird dann zuerst diese Methode aufgerufen, die damit das »Hauptprogramm« bildet.
Dateien mit Klassendefinitionen werden in Java mit der Endung
.java gespeichert, wobei für jede öffentliche, d.h. von »außen« nutzbare Klasse eine eigene Datei verwendet wird, die den Namen der Klasse trägt. Die Klassen müssen zur Erstellung eines ausführbaren Programms zunächst mit dem Java-Compiler in Bytecode übersetzt wer-
1.4 Grundkonzepte der Programmierung in Java
Abbildung 1.2
Struktur eines
Java-Programms
Programm
public class EineKlasse {
// Attribute
int einAttribut;
11
Klassendatei
// Methoden
void eineMethode () { … }
}
Klassendatei
public class EineAndereKlasse {
// Methoden
void nochEineMethode () { … }
public static void main (String[] args) { … }
main-Methode
}
den. Der Java-Compiler ist entweder in eine Entwicklungsumgebung
integriert oder als ein Programm mit dem Namen javac verfügbar.
Im ersten Fall erfolgt die Übersetzung einfach über die grafische Benutzerschnittstelle der Entwicklungsumgebung. Im zweiten Fall muss dies
durch ein Kommando der folgenden Form vorgenommen werden:
Übersetzung
> javac Klasse.java
Als Ergebnis der Übersetzung entsteht für jede Klasse eine Datei mit
der Endung .class, die den Bytecode enthält und durch den JavaInterpreter ausführbar ist. Ein explizites Binden der übersetzten Klassen, wie es etwa bei C-Programmen durchgeführt werden muss, ist dagegen nicht notwendig. Zur Ausführung muss der Interpreter – ein Programm mit dem Namen java – gestartet werden, wobei der Name der
Klasse als Parameter übergeben wird. Sind in der auszuführenden Klasse weitere Klassen referenziert, so wird der benötigte Bytecode vom
Interpreter bei Bedarf nachgeladen. Dazu muss bekannt sein, wo dieser
Code zu finden ist. Sowohl Compiler als auch Interpreter werten daher
eine Umgebungsvariable CLASSPATH aus, die eine Liste von Verzeichnissen bzw. von Archiven mit .class-Dateien beinhaltet. Im einfachsten Fall ist dies das aktuelle Verzeichnis, das durch ».« bezeichnet wird.
Sollen mehrere Verzeichnisse angegeben werden, so werden diese unter
UNIX durch »:« bzw. unter Windows durch »;« getrennt.
Ein weiteres wichtiges Strukturierungsmittel in Java sind Packages
oder Pakete. Hierbei handelt es sich um einen Mechanismus zur Organisation von Java-Klassen. Durch Pakete werden Namensräume gebildet, die Konflikte durch gleiche Bezeichnungen verhindern. So kann
eine Klasse Object definiert werden, ohne dass es dadurch zu Konflikten mit der Standardklasse java.lang.Object kommt. Ein Paket
demo wird beispielsweise durch die Anweisung
Ausführung
CLASSPATH
Package
12
1 Vorbemerkungen und Überblick
package demo;
Importieren
vereinbart, wobei dies am Anfang der Quelldatei anzugeben ist. Jede Klasse, in deren Quelldatei diese Anweisung steht, wird dem Paket demo zugeordnet. Über die Notation demo.MeineKlasse kann
danach eindeutig die im Paket demo definierte Klasse MeineKlasse
identifiziert werden. Diese Schreibweise lässt sich jedoch abkürzen, indem zu Beginn der Quelldatei eine import-Anweisung eingefügt wird:
import demo.MeineKlasse;
Danach kann die Klasse MeineKlasse ohne vorangestellten Paketnamen verwendet werden. Alle Klassen eines Paketes lassen sich durch
Angabe eines * importieren:
import demo.*;
Paketnamen
Standard-API
Programm 1.1
»Hello World!« in
Java
Paketnamen können hierarchisch aufgebaut werden, wobei die einzelnen Namensbestandteile durch ».« getrennt werden. Allerdings wird
durch Angabe des »*« beim Import kein rekursives Importieren durchgeführt, sondern es sind nur die Klassen des bezeichneten Paketes betroffen. Zu beachten ist weiterhin, dass die Pakete, die mit java. beginnen, zum Standard-API gehören und nicht verändert werden dürfen,
d.h., eigene Paketnamen dürfen nicht mit java. beginnen.
Pakete liefern dem Java-Compiler auch Hinweise, wo die kompilierten Klassendateien (Dateien mit der Endung .class) abgelegt werden sollen. Danach werden Punkte im Paketnamen durch
den Separator für Verzeichnisnamen ersetzt. Eine Klassendatei der
Klasse algoj.sort.QuickSort wird demzufolge im Verzeichnis
algoj/sort unter dem Namen QuickSort.class abgelegt.
Betrachten wir nun am Beispiel einer einfachen Klasse die Schritte der Erstellung eines Java-Programms. Die Klasse Hello aus Programm 1.1 soll die typische Aufgabe eines jeden ersten Programms aus
Einführungsbüchern zu Programmiersprachen erfüllen: die Ausgabe der
Meldung »Hello World!«.
// Hello World! in Java
public class Hello {
public static void main(String[ ] args) {
System.out.println("Hello World!");
}
}
Für das Programm muss zunächst eine Klasse definiert werden, die
als »Kapsel« dient: Attribute und Methoden können nur im Rahmen
1.4 Grundkonzepte der Programmierung in Java
von Klassen definiert werden. Eine Klassendefinition wird durch das
Schlüsselwort class, gefolgt vom Bezeichner der Klasse, eingeleitet.
Das im obigen Programm vorangestellte Schlüsselwort public definiert zusätzlich noch die Sichtbarkeit der Klasse und gibt an, dass diese
Klasse öffentlich ist, d.h. auch von anderen Modulen aus zugreifbar ist.
Es sei an dieser Stelle noch betont, dass bei Java zwischen Groß- und
Kleinschreibung unterschieden wird: Die Schlüsselwörter der Sprache
(z.B. class) werden grundsätzlich kleingeschrieben, bei Bezeichnern
(wie etwa der Name einer Klasse) bleibt dies dem Entwickler überlassen, muss aber konsistent erfolgen. So bezeichnen eineKlasse,
EineKlasse und EINEKLASSE verschiedene Klassen!
Im Anschluss an den Klassenbezeichner folgt in geschweiften Klammern die Definition der Attribute und Methoden. In unserem Beispiel
umfasst die Klasse nur eine Methode main. Diese Methode ist öffentlich (public), liefert kein Ergebnis zurück (Typ void) und erwartet
als Parameter ein Feld von Zeichenketten (String[] args). Obwohl
die Parameter in unserem Beispiel nicht benötigt werden, müssen sie
dennoch hier angegeben werden, da der Java-Interpreter eine Methode
mit exakt der Signatur static void main (String[]) sucht und
aufruft. Das Schlüsselwort static kennzeichnet die Methode als Klassenmethode, d.h., sie kann ohne Objekt aufgerufen werden. Da wir die
Konzepte der Objektorientierung erst in Kapitel 11 behandeln, werden
wir zunächst alle Methoden als Klassenmethoden realisieren.
Die main-Methode besteht nur aus einer Anweisung zur Ausgabe
der Zeichenkette »Hello World!« auf den Bildschirm. Diese Anweisung
ist der Aufruf der Methode println. Das vorangestelle System.out
bezeichnet das Objekt, für das diese Methode aufgerufen wird – es handelt sich hier konkret um ein Objekt, das durch das Attribut out der
Klasse System bezeichnet wird und die Ausgabe repräsentiert.
Ein Kommentar im Quelltext wird durch das Voranstellen der Zeichenfolge // gekennzeichnet. In diesem Fall erstreckt sich der Kommentar bis zum Zeilenende. Eine zweite Möglichkeit ist das Einschließen in
/* Kommentar */. Hier kann sich der Kommentar auch über mehrere
Zeilen erstrecken.
Der Quelltext der obigen Klasse Hello wird in einer Datei
Hello.java gesichert und mit Hilfe des Compilers übersetzt:
> javac Hello.java
Schließlich wird der erzeugte Bytecode mit dem Interpreter ausgeführt
und dabei die Meldung »Hello World!« ausgegeben:
> java Hello
Hello World!
13
Klassenbezeichner
Definition der
Attribute und
Methoden
Klassenmethode
Ausgabe
Kommentar
Übersetzung
14
1 Vorbemerkungen und Überblick
Applet
Zu beachten ist, dass nur der Name der auszuführenden Klasse als Parameter angegeben wird und nicht der vollständige Dateiname.
Eine spezielle Form von Java-Programmen sind die Applets. Hierbei handelt es sich um kleine Module, die im Rahmen von Webseiten in
einem Web-Browser ausgeführt werden. Daraus ergibt sich, dass diese
Applets gemeinsam mit dem Dokument vom Web-Server geladen werden – das Installieren von Programmen kann damit entfallen. Applets
dienen vor allem zur Gestaltung aktiver Elemente in Webseiten. Sie ermöglichen es, Anwendungslogik im Form von Java-Code im Browser
auszuführen. So lassen sich beispielsweise Spiele realisieren oder Daten
aus anderen Quellen interaktiv präsentieren und manipulieren. Ähnliche Konzepte existieren inzwischen auch für die Ausführung von JavaProgrammen auf Mobiltelefonen. Da Applets jedoch aus Sicht der Programmierung keine wesentlichen Unterschiede aufweisen, werden wir
uns im Weiteren auf »normale« Java-Programme beschränken.
Herunterladen