Marco Cantù 1998, Mastering Delphi 4
Project: MULTINH.DPR
Project Structure
MULTINH.DPR
program MultInh;
uses
Forms,
MultForm in 'MultForm.pas' {FormAnimMi},
MultAnim in 'MultAnim.pas';
{$R *.RES}
begin
Application.Initialize;
Application.CreateForm(TFormAnimMi, FormAnimMi);
Application.Run;
end.
MULTFORM.PAS
unit MultForm;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, MultAnim;
type
TFormAnimMi = class(TForm)
BtnKind: TButton;
BtnFly: TButton;
Memo1: TMemo;
BtnSwim: TButton;
BtnWalk: TButton;
BtnDuck: TButton;
BtnKindI: TButton;
BtnFlyI: TButton;
BtnSwimI: TButton;
BtnWalkI: TButton;
Label1: TLabel;
Label2: TLabel;
BtnMammalsI: TButton;
procedure BtnKindClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure BtnFlyClick(Sender: TObject);
procedure BtnSwimClick(Sender: TObject);
procedure BtnWalkClick(Sender: TObject);
procedure BtnDuckClick(Sender: TObject);
procedure BtnKindIClick(Sender: TObject);
procedure BtnFlyIClick(Sender: TObject);
procedure BtnSwimIClick(Sender: TObject);
procedure BtnWalkIClick(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure BtnMammalsIClick(Sender: TObject);
private
Animals: array [1..5] of TAnimal;
AnimIntf: array [1..5] of IAnimal;
end;
var
FormAnimMi: TFormAnimMi;
implementation
{$R *.DFM}
procedure TFormAnimMi.FormCreate(Sender: TObject);
var
I: Integer;
begin
Animals[1] := TEagle.Create;
Animals[2] := TPenguin.Create;
Animals[3] := TDuck.Create;
Animals[4] := TBat.Create;
Animals[5] := TMonkey.Create;
for I := 1 to 5 do
(Animals[I] as IAnimal)._AddRef;
AnimIntf[1] := TEagle.Create;
AnimIntf[2] := TPenguin.Create;
AnimIntf[3] := TDuck.Create;
AnimIntf[4] := TBat.Create;
AnimIntf[5] := TMonkey.Create;
end;
procedure TFormAnimMi.BtnKindClick(Sender: TObject);
var
I: Integer;
begin
Memo1.Lines.Add ('Kinds:');
for I := 1 to 5 do
// standard polymorphic method call
Memo1.Lines.Add (Animals[I].Kind);
Memo1.Lines.Add ('');
end;
procedure TFormAnimMi.BtnFlyClick(Sender: TObject);
var
I: Integer;
Fly1: ICanFly;
begin
Fly1 := nil;
Memo1.Lines.Add ('Fly:');
for I := 1 to 5 do
begin
Animals[i].GetInterface (ICanFly, Fly1);
if Assigned (Fly1) then
Memo1.Lines.Add (Fly1.Fly);
end;
Memo1.Lines.Add ('');
end;
procedure TFormAnimMi.BtnSwimClick(Sender: TObject);
var
I: Integer;
Swim1: ICanSwim;
begin
Memo1.Lines.Add ('Swim:');
for I := 1 to 5 do
if Animals[i].GetInterface (ICanSwim, Swim1) then
Memo1.Lines.Add (Swim1.Swim);
Memo1.Lines.Add ('');
end;
procedure TFormAnimMi.BtnWalkClick(Sender: TObject);
var
I: Integer;
Walker1: ICanWalk;
begin
Memo1.Lines.Add ('Walk:');
for I := 1 to 5 do
try
Walker1 := Animals[i] as ICanWalk;
Memo1.Lines.Add (Walker1.Walk);
except;
end;
Memo1.Lines.Add ('');
end;
procedure TFormAnimMi.BtnDuckClick(Sender: TObject);
var
I: Integer;
Duck1: TDuck;
begin
Memo1.Lines.Add ('Duck:');
for I := 1 to 5 do
if Animals[I] is TDuck then
begin
Duck1 := TDuck (Animals[I]);
Memo1.Lines.Add (Duck1.Kind);
Memo1.Lines.Add (Duck1.Walk);
Memo1.Lines.Add (Duck1.Fly);
Memo1.Lines.Add (Duck1.Swim);
Memo1.Lines.Add (Duck1.LayEggs);
Memo1.Lines.Add (IntToStr(Duck1.RefCount));
end;
end;
procedure TFormAnimMi.BtnKindIClick(Sender: TObject);
var
I: Integer;
begin
Memo1.Lines.Add ('Kinds:');
for I := 1 to 5 do
// standard polymorphic method call
Memo1.Lines.Add (AnimIntf[I].Kind);
Memo1.Lines.Add ('');
end;
procedure TFormAnimMi.BtnFlyIClick(Sender: TObject);
var
I: Integer;
Fly1: ICanFly;
begin
Memo1.Lines.Add ('Fly:');
for I := 1 to 5 do
begin
AnimIntf[i].QueryInterface (ICanFly, Fly1);
if Assigned (Fly1) then
Memo1.Lines.Add (Fly1.Fly);
end;
Memo1.Lines.Add ('');
end;
procedure TFormAnimMi.BtnSwimIClick(Sender: TObject);
var
I: Integer;
Swim1: ICanSwim;
begin
Memo1.Lines.Add ('Swim:');
for I := 1 to 5 do
if AnimIntf[i].QueryInterface (
ICanSwim, Swim1) <> E_NoInterface then
Memo1.Lines.Add (Swim1.Swim);
Memo1.Lines.Add ('');
end;
procedure TFormAnimMi.BtnWalkIClick(Sender: TObject);
var
I: Integer;
Walker1: ICanWalk;
begin
Memo1.Lines.Add ('Walk:');
for I := 1 to 5 do
try
Walker1 := AnimIntf[i] as ICanWalk;
Memo1.Lines.Add (Walker1.Walk);
except
end;
Memo1.Lines.Add ('');
end;
procedure TFormAnimMi.FormDestroy(Sender: TObject);
var
I: Integer;
begin
for I := 1 to 5 do
Animals[I].Free;
end;
procedure TFormAnimMi.BtnMammalsIClick(Sender: TObject);
var
I: Integer;
Mam1: IMammal;
begin
Memo1.Lines.Add ('Mammals:');
for I := 1 to 5 do
begin
AnimIntf[i].QueryInterface (IMammal, Mam1);
if Assigned (Mam1) then
Memo1.Lines.Add (Mam1.Kind);
end;
Memo1.Lines.Add ('');
end;
end.
MULTANIM.PAS
unit MultAnim;
interface
type
IAnimal = interface
['{248CC900-64CB-11D1-98D1-004845400FAA}']
function Kind: string;
end;
ICanFly = interface (IAnimal)
['{248CC901-64CB-11D1-98D1-004845400FAA}']
function Fly: string;
end;
ICanWalk = interface (IAnimal)
['{248CC902-64CB-11D1-98D1-004845400FAA}']
function Walk: string;
end;
ICanSwim = interface (IAnimal)
['{248CC903-64CB-11D1-98D1-004845400FAA}']
function Swim: string;
end;
IMammal = interface (IAnimal)
['{248CC904-64CB-11D1-98D1-004845400FAA}']
function CarryChild: string;
end;
IBird = interface (IAnimal)
['{248CC905-64CB-11D1-98D1-004845400FAA}']
function LayEggs: string;
end;
TAnimal = class (TInterfacedObject, IAnimal)
function Kind: string; virtual; abstract;
destructor Destroy; override;
end;
TMammal = class (TAnimal, IMammal)
function CarryChild: string; virtual;
end;
TBird = class (TAnimal, IBird)
function LayEggs: string; virtual;
end;
TEagle = class (TBird, ICanFly)
function Kind: string; override;
function Fly: string; virtual;
end;
TPenguin = class (TBird, ICanWalk, ICanSwim)
function Kind: string; override;
function Walk: string; virtual;
function Swim: string; virtual;
end;
TDuck = class (TBird, ICanWalk, ICanFly, ICanSwim)
function Kind: string; override;
function Walk: string; virtual;
function Fly: string; virtual;
function Swim: string; virtual;
end;
TBat = class (TMammal, ICanFly)
function Kind: string; override;
function Fly: string; virtual;
end;
TMonkey = class (TMammal, ICanWalk)
function Kind: string; override;
function Walk: string; virtual;
end;
implementation
uses
Windows;
destructor TAnimal.Destroy;
begin
// MessageBox (0, pChar ('Destroying ' + Kind),
// 'Anim MI', MB_OK);
inherited;
end;
function TMammal.CarryChild: string;
begin
Result := 'Female mammals carry children for months';
end;
function TBird.LayEggs: string;
begin
Result := 'Birds lay eggs';
end;
function TEagle.Kind: string;
begin
Result := 'Eagle';
end;
function TEagle.Fly: string;
begin
Result := 'Eagles fly over mountains';
end;
function TPenguin.Kind: string;
begin
Result := 'Penguin';
end;
function TPenguin.Walk: string;
begin
Result := 'Penguins walk on ice';
end;
function TPenguin.Swim: string;
begin
Result := 'Penguins swim better than they walk';
end;
function TBat.Kind: string;
begin
Result := 'Bat';
end;
function TBat.Fly: string;
begin
Result := 'Bats fly in the night';
end;
function TDuck.Kind: string;
begin
Result := 'Duck';
end;
function TDuck.Walk: string;
begin
Result := 'Ducks walk in a funny way';
end;
function TDuck.Fly: string;
begin
Result := 'Ducks fly and migrate';
end;
function TDuck.Swim: string;
begin
Result := 'Ducks swim as well';
end;
function TMonkey.Kind: string;
begin
Result := 'Monkey';
end;
function TMonkey.Walk: string;
begin
Result := 'A walking monkey';
end;
end.
MULTFORM.DFM
object FormAnimMi: TFormAnimMi
Left = 194
Top = 116
Width = 596
Height = 305
Caption = 'Anim MI'
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = []
OnCreate = FormCreate
OnDestroy = FormDestroy
PixelsPerInch = 96
TextHeight = 13
object Label1: TLabel
Left = 8
Top = 16
Width = 44
Height = 13
Caption = 'Objects'
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = [fsBold]
ParentFont = False
end
object Label2: TLabel
Left = 440
Top = 16
Width = 58
Height = 13
Caption = 'Interfaces'
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'MS Sans Serif'
Font.Style = [fsBold]
ParentFont = False
end
object BtnKind: TButton
Left = 8
Top = 40
Width = 145
Height = 25
Caption = 'Animals kind'
TabOrder = 0
OnClick = BtnKindClick
end
object BtnFly: TButton
Left = 8
Top = 72
Width = 145
Height = 25
Caption = 'Animals fly'
TabOrder = 1
OnClick = BtnFlyClick
end
object Memo1: TMemo
Left = 160
Top = 16
Width = 265
Height = 249
ScrollBars = ssVertical
TabOrder = 2
end
object BtnSwim: TButton
Left = 8
Top = 104
Width = 145
Height = 25
Caption = 'Animals swim '
TabOrder = 3
OnClick = BtnSwimClick
end
object BtnWalk: TButton
Left = 8
Top = 136
Width = 145
Height = 25
Caption = 'Animals walk'
TabOrder = 4
OnClick = BtnWalkClick
end
object BtnDuck: TButton
Left = 8
Top = 184
Width = 145
Height = 25
Caption = 'As Duck'
TabOrder = 5
OnClick = BtnDuckClick
end
object BtnKindI: TButton
Left = 440
Top = 40
Width = 145
Height = 25
Caption = 'Animals kind'
TabOrder = 6
OnClick = BtnKindIClick
end
object BtnFlyI: TButton
Left = 440
Top = 72
Width = 145
Height = 25
Caption = 'Animals fly'
TabOrder = 7
OnClick = BtnFlyIClick
end
object BtnSwimI: TButton
Left = 440
Top = 104
Width = 145
Height = 25
Caption = 'Animals swim '
TabOrder = 8
OnClick = BtnSwimIClick
end
object BtnWalkI: TButton
Left = 440
Top = 136
Width = 145
Height = 25
Caption = 'Animals walk'
TabOrder = 9
OnClick = BtnWalkIClick
end
object BtnMammalsI: TButton
Left = 440
Top = 184
Width = 145
Height = 25
Caption = 'List Mammals'
TabOrder = 10
OnClick = BtnMammalsIClick
end
end
Copyright Marco Cantù 1998