Sprach-Übersicht

Aus RAD Studio
Wechseln zu: Navigation, Suche

Nach oben zu Delphi-Sprachreferenz - Index

Delphi ist eine höhere Compiler-Sprache mit strenger Typisierung, die eine strukturierte und objektorientierte Programmierung ermöglicht. Sie basiert auf Objekt Pascal. Zu ihren Vorzügen gehören einfache Lesbarkeit, schnelle Compilierung und modulare Programmierung durch Verteilen des Quelltextes auf mehrere Unit-Dateien. Delphi verfügt über spezielle Leistungsmerkmale, die das Komponentenmodell und die visuelle Entwicklungsumgebung von Embarcadero unterstützen. In den Beschreibungen und Beispielen dieser Sprachreferenz wird davon ausgegangen, dass Sie die Embarcadero-Entwicklungstools verwenden.


Die meisten Entwickler, die mit Software-Entwicklungstools von Embarcadero arbeiten, schreiben und compilieren ihre Programme in der integrierten Entwicklungsumgebung (IDE). Hier kümmert sich das Entwicklungstool um viele Details, die beim Einrichten von Projekten und Quelltextdateien von Bedeutung sind (z. B. Verwalten der Abhängigkeiten zwischen den Units). Dabei gelten Regeln bezüglich der Programmorganisation, die aber nicht zur Sprachdefinition von Object Pascal gehören. So werden beispielsweise bestimmte Namenskonventionen für Dateien und Programme verwendet, an die Sie aber nicht gebunden sind, wenn Sie Programme außerhalb der IDE schreiben und in der Befehlszeile compilieren.

Im allgemeinen geht diese Sprachreferenz davon aus, dass Sie in der IDE arbeiten und Anwendungen mithilfe der Embarcadero-VCL (Visual Component Library) erstellen. Wo es erforderlich ist, wird jedoch zwischen Delphi-spezifischen Regeln und der normalen Programmierung mit Object Pascal unterschieden. Beschrieben werden die Delphi-Compiler für Win32 und für die .NET-Plattform. Auf plattformspezifische Unterschiede und Funktionen wird bei Bedarf hingewiesen.

Dieser Abschnitt enthält Informationen zu folgenden Themen:

  • Programmorganisation. Eine Beschreibung der grundlegenden Leistungsmerkmale der Sprache, die das Aufteilen einer Anwendung in Units und Namespaces ermöglichen.
  • Beispielprogramme. Kurze Beispiele für Konsolen- und GUI-Anwendungen veranschaulichen die Verwendung des Befehlszeilen-Compilers.

Programmorganisation

Delphi-Programme werden normalerweise auf mehrere Quelltextmodule (so genannte Units) verteilt. Die meisten Programme beginnen mit einer program-Kopfzeile, in der der Programmname angegeben wird. Darauf folgt eine optionale uses-Klausel und ein Block von Deklarationen und Anweisungen. Mit der uses-Klausel geben Sie die Units an, die in das Programm eingebunden werden. Units können von mehreren Programmen gemeinsam benutzt werden und verfügen häufig über eigene uses-Klauseln.

Die uses-Klausel liefert dem Compiler Informationen über die Modulabhängigkeiten. Da diese Abhängigkeiten in den Modulen selbst gespeichert werden, benötigen die meisten Delphi-Programme keine Make-Dateien, Header-Dateien oder #include-Präprozessordirektiven.

Delphi-Quelltextdateien

Der Compiler erwartet Delphi-Quelltexte in einem der folgenden Dateitypen:

  • Unit-Quelltextdateien mit der Namenserweiterung .PAS
  • Projektdateien mit der Namenserweiterung .DPR
  • Package-Quelltextdateien mit der Namenserweiterung .DPK

In den Unit-Quelltextdateien befindet sich in der Regel der größte Teil des Programmcodes. Jede Anwendung besteht aus einer Projektdatei und mehreren Unit-Dateien. Die Projektdatei entspricht dem Hauptprogramm im herkömmlichen Pascal und organisiert die Units der Anwendung. Embarcadero-Entwicklungstools verwalten für jede Anwendung automatisch eine Projektdatei.

Wenn Sie ein Programm in der Befehlszeile compilieren, können Sie den gesamten Quelltext in Unit-Dateien (.PAS) aufnehmen. Erstellen Sie die Anwendung jedoch mithilfe der IDE, wird eine Projektdatei (.DPR) angelegt.

Package-Quelltextdateien ähneln Projektdateien, werden aber für spezielle, dynamisch ladbare Bibliotheken (so genannte Packages) verwendet.

Weitere Anwendungsdateien

Embarcadero-Produkte verwenden neben den Quelltextmodulen auch die folgenden Dateitypen, die keinen Pascal-Code enthalten und ebenfalls automatisch von der IDE verwaltet werden:

  • VCL-Formulardateien mit der Namenserweiterung .DFM (Win32) oder .NFM (.NET)
  • Ressourcendateien mit der Namenserweiterung .RES
  • Projektdateien mit der Namenserweiterung .DOF

Eine VCL-Formulardatei enthält die Beschreibung der Eigenschaften des Formulars und seiner Komponenten. Sie repräsentiert ein Formular, das normalerweise einem Fenster oder Dialogfeld in einer Anwendung entspricht. Formulardateien können in der IDE als Text angezeigt und bearbeitet und danach entweder im Text- oder im Binärformat gespeichert werden. (Das Textformat eignet sich hervorragend zur Versionskontrolle.) Obwohl Formulardateien standardmäßig als Text gespeichert werden, ist eine manuelle Bearbeitung nicht üblich. Normalerweise werden dazu die visuellen Tools von Embarcadero verwendet. Jedes Projekt hat mindestens ein Formular. Zu jedem Formular gehört eine Unit-Datei (.PAS), die standardmäßig denselben Namen wie die Formulardatei erhält.

Zusätzlich zu den VCL-Formulardateien verwendet jedes Projekt eine Ressourcendatei (.RES), in der das Anwendungssymbol und andere Ressourcen, wie Strings, gespeichert werden. Diese Datei erhält automatisch denselben Namen wie die Projektdatei (.DPR).

Die Projektoptionsdatei (.DOF) enthält Compiler- und Linker-Einstellungen, Suchpfadinformationen, Versionsinformationen usw. Diese Datei erhält automatisch denselben Namen wie die Projektdatei (.DPR). Die Einstellungen in dieser Datei können im Dialogfeld Projektoptionen festgelegt werden.

Verschiedene Tools in der IDE speichern Daten in speziellen Dateitypen. Desktop-Konfigurationsdateien (.DSK) enthalten Informationen über die Anordnung der Fenster und andere Konfigurationseinstellungen. Desktop-Einstellungen können projektspezifisch sein oder für die gesamte Umgebung gelten. Die Desktop-Konfigurationsdateien haben keine direkten Auswirkungen auf die Compilierung.

Vom Compiler generierte Dateien

Wenn Sie eine Anwendung oder ein Package zum ersten Mal erstellen, generiert der Compiler für jede im Projekt verwendete Unit eine compilierte Unit-Datei (.DCU für Win32 ). Diese Dateien werden dann zu einer ausführbaren Datei bzw. zu einem gemeinsam genutzten Package gelinkt. Bei der ersten Erstellung eines Package wird für jede im Package enthaltene neue Unit eine Datei erstellt. Danach generiert der Compiler eine .DCP- und eine Package-Datei. Wenn der Befehlszeilenschalter GD verwendet wird, generiert der Linker eine Map- und eine .DRC-Datei. Die .DRC-Datei enthält String-Ressourcen und kann in eine Ressourcendatei compiliert werden.

Beim Erstellen eines Projekts wird eine Unit nur dann erneut compiliert, wenn ihre Quelltextdatei (.PAS) seit dem letzten Compilieren geändert wurde, die zugehörige .DCU/.DPU-Datei nicht gefunden werden kann, der Compiler explizit dazu angewiesen wird oder das Interface der Unit von einer anderen Unit abhängig ist, die geändert wurde. Wenn der Compiler auf die entsprechende compilierte Unit-Datei zugreifen kann und die Unit nicht von anderen Units abhängig ist, die geändert wurden, wird die Quelltextdatei der Unit nicht benötigt.

Beispielprogramme

Die folgenden Beispielprogramme zeigen die Grundzüge der Programmierung mit Delphi. Es handelt sich um einfache Anwendungen, die nicht in der IDE, sondern nur in der Befehlszeile compiliert werden können.

Eine einfache Konsolenanwendung

Das folgende Beispiel zeigt eine einfache Konsolenanwendung, die Sie in der Befehlszeile compilieren und ausführen können.

 program greeting;
 
 {$APPTYPE CONSOLE}
 
 var 
   MyMessage: string;
 
 begin
   MyMessage := 'Hello world!';
   Writeln(MyMessage);
 end.

Durch die erste Anweisung wird das Programm Greeting deklariert. Die Direktive {$APPTYPE CONSOLE} teilt dem Compiler mit, dass es sich um eine Konsolenanwendung handelt, die in der Befehlszeile ausgeführt wird. In der nächsten Zeile wird die String-Variable MyMessage deklariert (in Delphi gibt es echte String-Datentypen). Im Programmblock wird der Variable MyMessage der String "Hello world!" zugewiesen. Anschließend wird die Variable mit der Standardprozedur Writeln an die Standardausgabe gesendet. (Writeln ist implizit in der Unit System definiert, die automatisch in jede Anwendung eingebunden wird).

Sie können nun das Programm in eine Datei mit dem Namen greeting.pas oder greeting.dpr eingeben und dann compilieren:

dcc32 greeting

Hiermit erhalten Sie eine ausführbare Win32-Datei.

Die ergebende ausführbare Datei gibt die Meldung Hello world! auf dem Bildschirm aus.

Neben seiner Einfachheit unterscheidet sich dieses Beispiel noch in anderen wichtigen Punkten von den Anwendungen, die Sie normalerweise mit Embarcadero-Entwicklungstools erstellen. Zum einen handelt es sich bei dem Beispiel um eine Konsolenanwendung. Mit Embarcadero-Entwicklungstools werden hauptsächlich Anwendungen mit grafischen Benutzeroberflächen entwickelt, in denen natürlich keine Writeln-Aufrufe benötigt werden. Außerdem befindet sich das gesamte Beispielprogramm (abgesehen von Writeln) in einer einzigen Datei. Bei einer typischen GUI-Anwendung steht der Programmkopf (im Beispiel die erste Zeile) in einer separaten Projektdatei, die mit Ausnahme einiger Routinenaufrufe keinerlei Programmlogik enthält.

Ein komplexeres Beispiel

Das Programm im nächsten Beispiel ist auf zwei Dateien verteilt, eine Projektdatei und eine Unit-Datei. Die Projektdatei, die Sie unter dem Namen greeting.dpr speichern können, hat folgenden Inhalt:

 
 program greeting;
 
 {$APPTYPE CONSOLE}
 
 uses 
   Unit1;
 
 begin
   PrintMessage('Hello World!');
 end.

In der ersten Zeile wird das Programm greeting deklariert, das wiederum eine Konsolenanwendung ist. Über die Klausel uses Unit1; wird dem Compiler mitgeteilt, dass das Programm greeting von einer Unit namens Unit1 abhängig ist. Zum Schluss wird die Prozedur PrintMessage mit dem String Hello World! aufgerufen. Die Prozedur PrintMessage ist in Unit1 definiert. Unit1 hat folgenden Inhalt (speichern Sie sie unter dem Namen Unit1.pas):

 
 unit Unit1;
 
 interface
 
 procedure PrintMessage(msg: string);
 
 implementation
 
 procedure PrintMessage(msg: string);
 begin
    Writeln(msg);
 end;
 
 end.

Unit1 definiert eine Prozedur namens PrintMessage, die einen String als Argument übernimmt und diesen String an die Standardausgabe sendet. (In Delphi heißen Routinen ohne Rückgabewert Prozeduren. Routinen, die einen Wert zurückgeben, heißen Funktionen.)

Beachten Sie, dass PrintMessage zweimal in Unit1 deklariert ist. Die erste Deklaration im interface-Abschnitt macht PrintMessage für andere Module verfügbar (z. B. für das Programm greeting), die Unit1 einbinden. Durch die zweite Deklaration (im implementation-Abschnitt) erfolgt die eigentliche Definition der Prozedur PrintMessage.

Sie können greeting nun in der Befehlszeile compilieren:

dcc32 greeting

Hiermit erhalten Sie eine ausführbare Win32-Datei.

Unit1 braucht in der Befehlszeile nicht angegeben zu werden. Der Compiler liest beim Bearbeiten von greeting.dpr automatisch die Unit-Dateien ein, von denen greeting abhängig ist. Die neue ausführbare Datei führt dieselbe Operation durch wie im ersten Beispiel, gibt also die Meldung Hello world! aus.

Eine VCL-Anwendung

Als nächstes erstellen wir eine Anwendung mithilfe von VCL-Komponenten (VCL, Visual Component Library) in der IDE. Im Programm werden die automatisch generierten Formular- und Ressourcendateien verwendet. Es kann daher nicht allein aus dem Quelltext compiliert werden. Das Beispiel zeigt einige wichtige Merkmale von Delphi. Neben mehreren Units werden auch Klassen und Objekte verwendet.

Die Anwendung besteht aus einer Projektdatei und zwei neuen Unit-Dateien. Betrachten wir zuerst die Projektdatei:

 program greeting;

 uses 
   Forms, Unit1, Unit2;

 {$R *.res} { Diese Direktive linkt die Ressourcendatei des Projekts. }
 
 begin
    { Aufruf der globalen Application-Instanz Application
    Application.Initialize;
    Application.CreateForm(TForm1, Form1);
    Application.CreateForm(TForm2, Form2);
    Application.Run;
 end.

Unser Programm heißt auch diesmal greeting. Es werden drei Units eingebunden: Forms ist ein Bestandteil der VCL, Unit1 gehört zum Hauptformular der Anwendung (Form1) und Unit2 zu einem weiteren Formular (Form2).

In Programm finden mehrere Aufrufe des Objekts Application statt, das eine Instanz der in Forms deklarierten Klasse Vcl.Forms.TApplication ist (für jedes Projekt wird automatisch ein Application-Objekt erstellt). Die Methode CreateForm von Vcl.Forms.TApplication wird zweimal aufgerufen. Durch den ersten Aufruf CreateForm wird Form1 erstellt, eine Instanz der in Unit1 deklarierten Klasse TForm1. Durch den zweiten Aufruf von CreateForm wird Form2 erstellt, eine Instanz der in Unit2 deklarierten Klasse TForm2.

Unit1 hat folgenden Inhalt:

 unit Unit1;
 
 interface
 
 uses SysUtils, Types, Classes, Graphics, Controls, Forms, Dialogs;
 
 type
   TForm1 = class(TForm)
     Button1: TButton;
     procedure Button1Click(Sender: TObject);
   end;
 
 var
   Form1: TForm1;
 
 implementation
 
 uses Unit2;
 
 {$R *.dfm}
 
 procedure TForm1.Button1Click(Sender: TObject);
   begin
     Form2.ShowModal;
   end;
 
 end.

Unit1 erstellt eine Klasse namens TForm1 (abgeleitet von Vcl.Forms.TForm) und eine Instanz dieser Klasse (Form1). Die Klasse TForm1 enthält eine Schaltfläche Button1 (eine Instanz von Vcl.StdCtrls.TButton) und die Prozedur Button1Click, die aufgerufen wird, wenn der Benutzer auf Button1 klickt. Button1Click verbirgt Form1 und zeigt Form2 an (durch den Aufruf von Form2.ShowModal).

Hinweis: Im vorhergehenden Beispiel ist Form2.ShowModal von automatisch erstellten Formularen abhängig. Auch wenn sich solche Formulare gut für Beispielcode eignen, wird von ihrer Verwendung doch ausdrücklich abgeraten.

Das Objekt Form2 ist in Unit2 definiert:

 unit Unit2;
 
 interface
 
 uses SysUtils, Types, Classes, Graphics, Controls, Forms, Dialogs;
 
 type
 TForm2 = class(TForm)
   Label1: TLabel;
   CancelButton: TButton;
   procedure CancelButtonClick(Sender: TObject);
 end;
 
 var
   Form2: TForm2;
 
 implementation
 
 uses Unit1;
 
 {$R *.dfm}
 
 procedure TForm2.CancelButtonClick(Sender: TObject);
   begin
    Form2.Close;
   end;
 
 end.

Unit2 erstellt eine Klasse namens TForm2 und eine Instanz dieser Klasse (Form2). Die Klasse TForm2 enthält eine Schaltfläche (CancelButton, eine Instanz von Vcl.StdCtrls.TButton) und eine Beschriftung (Label1, eine Instanz von Vcl.StdCtrls.TLabel). Obwohl es aus dem Quelltext nicht ersichtlich ist, zeigt Label1 unseren Lieblingsgruß Hello world! an. Die Komponente ist in der Formulardatei von Form2, Unit2.dfm, definiert.

TForm2 deklariert und definiert die Methode CancelButtonClick, die zur Laufzeit aufgerufen wird, wenn der Benutzer auf die Schaltfläche CancelButton klickt. Solche Prozeduren (wie auch TForm1.Button1Click in Unit1) nennt man Ereignisbehandlungsroutinen, weil sie auf Ereignisse reagieren, die zur Laufzeit der Anwendung eintreten. Sie werden durch die Formulardateien für Form1 und Form2 bestimmten Ereignissen zugewiesen.

Nach dem Starten der Anwendung greeting wird lediglich Form1 angezeigt, während Form2 nicht sichtbar ist (standardmäßig ist nur das erste in der Projektdatei erstellte Formular, das Hauptformular, zur Laufzeit sichtbar). Klickt der Benutzer auf die Schaltfläche in Form1, wird in Form2 die Meldung Hello world! angezeigt. Wenn der Benutzer auf CancelButton oder auf das Schließfeld Close in der Titelleiste klickt, wird Form2 geschlossen.

Siehe auch