25. Objektorientierte Programmierung
Begriffe
Die klassischen Programmiersprachen arbeiten mit Daten und Prozeduren bzw. Funktionen, man sagt auch prozedural.
Beim Objektorientierten Programmieren (OOP) werden beide zu Objekten zusammengefasst und Attribute und Methoden genannt.
Attribute können Felder sein, auf die direkt zugegriffen wird oder Eigenschaften mit eigenen Lese- bzw. Schreibmethoden.
Definiert werden Objekte als Klassen, die deshalb auch Objekttypen heißen.
Konkrete Objekte erhält man, indem man Instanzen (Objektvariable) einer Klasse bildet.
Dies geschieht durch Aufruf der Create-Methode oder durch einen eigenen Konstruktor.
Von Klassen können Unterklassen gebildet werden, die alle Attribute und Methoden der Oberklasse erben und weitere dazu bekommen.
Klassen, die so stark verallgemeinert sind, dass erst von ihren Unterklassen sinnvoll Instanzen gebildet werden können, nennt man abstrakte Klassen.
In Delphi sind alle Klassen von der Klasse TObject abgeleitet.
Beispiel 1
Im ersten Beispiel wird in einer zweiten Unit eine Klasse deklariert, von der in der ersten Unit Instanzen erzeugt werden.
Die Klasse TPerson besteht aus den Feldern name, geburtsort und geburtsdatum und der Methode anzeigen.
unit Unit1;
interface
uses
Windows, Messages, ..., Unit2;
type
TForm1 = class(TForm)
Memo1: TMemo;
procedure FormCreate(Sender: TObject);
end;
var
Form1: TForm1;
person1, person2, person3 : TPerson;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
person1 := TPerson.Create;
person2 := TPerson.Create;
person3 := TPerson.Create;
person1.Fname := 'Hans Meier';
person1.Fgeburtstag := '1.1.1990';
person1.Fgeburtsort := 'Mannheim';
person2.Fname := 'Peter Schmidt';
person2.Fgeburtstag := '7.7.1990';
person2.Fgeburtsort := 'Heidelberg';
person3.Fname := 'Eva Walter';
person3.Fgeburtstag := '9.12.1990';
person3.Fgeburtsort := 'Heidelberg';
Memo1.Clear;
Memo1.Lines.Add(person1.anzeigen);
Memo1.Lines.Add(person2.anzeigen);
Memo1.Lines.Add(person3.anzeigen);
person1.free;
person2.free;
person3.free;
end;
end.
|
unit Unit2;
interface
type TPerson = class
Fname : string;
Fgeburtstag : string;
Fgeburtsort : string;
function anzeigen:string;
end;
implementation
function TPerson.anzeigen:string;
begin
result := Fname +', '
+ Fgeburtstag +', '
+ Fgeburtsort;
end;
end.
Das Formular enthält nur eine Memo-Komponente mit der Eigenschaft Align = alClient. |
Beispiel 2
Im zweiten Beispiel bilden wir eine Unterklasse Tschueler, die alle Attribute und Methoden von TPerson erbt und zusätzlich die Felder klasse und sprachen enthält.
unit Unit1;
interface
uses
Windows, ..., Unit2;
type
TForm1 = class(TForm)
Memo1: TMemo;
procedure FormCreate(Sender: TObject);
var
Form1: TForm1;
schueler1: TSchueler;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
schueler1 := Tschueler.create;
schueler1.Fname := 'Hans Meier';
schueler1.Fgeburtstag := '1.1.1970';
schueler1.Fgeburtsort := 'Mannheim';
schueler1.Fklasse := '10a';
schueler1.Fsprachen := 'EFL';
Memo1.Clear;
Memo1.Lines.Add(schueler1.anzeigen);
schueler1.free;
end;
end.
|
unit Unit2;
interface
type TPerson = class
Fname : string;
Fgeburtstag : string;
Fgeburtsort : string;
function anzeigen:string;
end;
type Tschueler = class(TPerson)
Fklasse : string;
Fsprachen : string;
function anzeigen:string;
end;
implementation
function TPerson.anzeigen:string;
begin
result := Fname +', '
+ Fgeburtstag +', '
+ Fgeburtsort;
end;
function Tschueler.anzeigen:string;
begin
result := inherited anzeigen;
result := result +', '
+ Fklasse +', '
+ Fsprachen;
end;
end.
|
Beispiel 3
Als nächstes erhält die Klasse Tperson einen eigenen Konstruktor mit dem die Felder initialisiert werden.
unit Unit1;
interface
uses
Windows, Messages, ..., Unit2;
type
TForm1 = class(TForm)
Memo1: TMemo;
procedure FormCreate(Sender: TObject);
end;
var
Form1: TForm1;
person1, person2, person3 : TPerson;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
person1 := TPerson.Create('Hans Meier',
'1.1.1990','Mannheim');
person2 := TPerson.Create('Peter Schmidt',
'7.7.1990','Heidelberg');
person3 := TPerson.Create('Eva Walter',
'9.12.1990','Heidelberg');
Memo1.Clear;
Memo1.Lines.Add(person1.anzeigen);
Memo1.Lines.Add(person2.anzeigen);
Memo1.Lines.Add(person3.anzeigen);
person1.free;
person2.free;
person3.free;
end;
end.
|
unit Unit2;
interface
type Tperson = class
Fname : string;
Fgeburtstag : string;
Fgeburtsort : string;
constructor Create(Fname,Fgeburtstag,
Fgeburtsort:string);
function anzeigen: string;
end;
implementation
constructor Tperson.Create;
begin
inherited Create;
self.Fname := Fname;
self.Fgeburtstag := Fgeburtstag;
self.Fgeburtsort := Fgeburtsort;
end;
function TPerson.anzeigen:string;
begin
result := Fname +', '
+ Fgeburtstag +', '
+ Fgeburtsort;
end;
end.
|
Beispiel 4
Ein wichtiges Prinzip beim Objektorientierten Programmieren ist das der Kapselung. Nach Möglichkeit soll nicht direkt auf die Felder des Objekts zugegriffen werden, sondern nur über eigene Zugriffsmethoden. Wir verpassen daher unserer Klasse Tperson die Eigenschaften (properties) name, geburtstag und geburtstort.
unit Unit1;
interface
uses
Windows, Messages, ..., Unit2;
type
TForm1 = class(TForm)
Memo1: TMemo;
procedure FormCreate(Sender: TObject);
var
Form1: TForm1;
person1: TPerson;
implementation
{$R *.dfm}
procedure TForm1.FormCreate(Sender: TObject);
begin
person1 := Tperson.create('Hans Meier',
'1.1.1970','Mannheim');
Memo1.Clear;
Memo1.Lines.Add('Name : ' + person1.name);
Memo1.Lines.Add('Geburtstag : ' + person1.geburtstag);
Memo1.Lines.Add('Geburtsort : ' + person1.geburtsort);
Memo1.Lines.Add('');
person1.name := 'Peter Schmidt';
person1.geburtstag := '7.7.1970';
person1.geburtsort := 'Heidelberg';
Memo1.Lines.Add('Name : ' + person1.name);
Memo1.Lines.Add('Geburtstag : ' + person1.geburtstag);
Memo1.Lines.Add('Geburtsort : ' + person1.geburtsort);
person1.free;
end;
end.
Der erste Eintrag erfolgt über den Konstruktor, der |
unit Unit2;
interface
type TPerson = class(TObject)
private
Fname : string;
Fgeburtstag : string;
Fgeburtsort : string;
function Getname:string;
procedure Setname(name:string);
function Getgebtag:string;
procedure Setgebtag(geburtstag:string);
function Getgebort:string;
procedure Setgebort(geburtsort:string);
public
constructor Create(Fname,Fgeburtstag,
Fgeburtsort:string);
property name:string read Getname
write Setname;
property geburtstag:string read Getgebtag
write Setgebtag;
property geburtsort:string read Getgebort
write Setgebort;
end;
implementation
function Tperson.Getname;
begin
result := Fname;
end;
function Tperson.Getgebtag;
begin
result := Fgeburtstag;
end;
function Tperson.Getgebort;
begin
result := Fgeburtsort;
end;
procedure Tperson.Setname;
begin
Fname := name;
end;
procedure Tperson.Setgebtag;
begin
Fgeburtstag := geburtstag;
end;
procedure Tperson.Setgebort;
begin
Fgeburtsort := geburtsort;
end;
constructor Tperson.Create;
begin
inherited Create;
self.Fname := Fname;
self.Fgeburtstag := Fgeburtstag;
self.Fgeburtsort := Fgeburtsort;
end;
end.
|
Aufgaben
Definiere eine Klasse Tbruch mit den Eigenschaften zaehler und nenner und den Methoden kuerzen, erweitern und bruchstr zur Ausgabe in der Form z/n. Bei der Schreibmethode für den Nenner soll die Eingabe von Null verhindert werden.
Definiere eine Klasse Tvektor mit den Eigenschaften x, y, z und den Methoden normieren, laenge und vektorstr zur Ausgabe in der Form (x|y|z).
Einführung in das Programmieren mit DELPHI
