Ein weiterer, sehr toller Aspekt an
OOP ist Polymorphie. Für mich ist das vielleicht sogar der entscheidende Punkt, da man ihn im Gegensatz zu Kapselung und Vererbung eigentlich nicht gescheit ohne Klassen simulieren kann (technisch möglich ist es natürlich, ist dann aber nicht mehr wirklich eleganter als Alternativen).
Delphi-Quellcode:
type
TShape = class
protected
FLeft, FTop, FSize: integer;
public
procedure DrawTo(Canvas: TCanvas); virtual; abstract;
property Left: integer read FLeft write FLeft;
property Top: integer read FTop write FTop;
property Size: integer read FSize write FSize;
end;
TCircle = class(TShape)
public
procedure DrawTo(Canvas: TCanvas); override;
end;
TSquare = class(TShape)
public
procedure DrawTo(Canvas: TCanvas); override;
end;
implementation
procedure TCircle.DrawTo(Canvas: TCanvas);
begin
Canvas.Ellipse(Left, Top, Left + Size, Top + Size);
end;
procedure TSquare.DrawTo(Canvas: TCanvas);
begin
Canvas.Rectangle(Left, Top, Left + Size, Top + Size);
end;
Delphi-Quellcode:
type
TMyForm = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure FormPaint(Sender: TObject);
private
FShapes: array[0..4] of TShape;
end;
implementation
procedure TMyForm.FormCreate(Sender: TObject);
begin
// *Irgendwelche* Formen z.B. in einem Array/Liste speichern.
// Konkreter Typ ist egal, solange sie nur von TShape erben.
for i := low(Shapes) to high(Shapes) do
begin
if Odd(i) then
Shapes[i] := TCircle.Create
else
Shapes[i] := TSquare.Create;
Shapes[i].Size := i * 5;
Shapes[i].Left := i * 20;
Shapes[i].Top := 0;
end;
end;
procedure TMyForm.FormPaint(Sender: TObject);
begin
// Wir können jetzt alle diese verschiedenen Objekte mit dem gleichen
// Code verarbeiten, obwohl es sich um verschiedenartige Klassen
// handelt und jeweils spezialisierter Code ausgeführt wird
// -> man spart sich u.U. etliche Case-Strukturen, die den Code
// sonst unübersichtlich und fehleranfällig machen würden
for i := low(Shapes) to high(Shapes) do
Shapes[i].DrawTo(Canvas);
end;
procedure TMyForm.FormDestroy(Sender: TObject);
begin
for i := low(Shapes) to high(Shapes) do
Shapes[i].Free;
end;
Mit records geht das einfach nicht so schön... vor allem nicht, wenn man später das Programm leicht um weitere Spezialisierungen erweitern können will.