unit COMCodeExample1_Unit;

{Project     : Abstract Method Example
Programming : Curtis W. Socha
Date        : 12/03/2000
References  : Delphi COM Programming

This coding example will attempt to explain the basic concepts
needed to understand how the reserved word "interface" works
and how this will lead to understanding how COM objects function.
}

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

type
  //This is our class that will only contain an
  //abstract|virtual method. No data is allowed in a
  //real interface so for the purposes of understanding the
  //concept, TFormattedNumber will not contain any data.
  //
  //Virtual is used so that the function is placed in the
  //VMT so it can be overridden by sub-classes. Many standard
  //Delphi component methods can be overriden because they
  //too are declared virtual and are placed in the VMT.
  //
  //Abstract is used do tell the compiler that there is no
  //implementation for this function, only that it exists
  //and will be implemented somewhere else.
  TFormattedNumber = class
  public
    function FormattedString : string; virtual; abstract;
  end;


  //This class inherits the abstract method FormattedString from
  //TFormattedNumber. It will override the method so that the
  //sub-class will implement the functionality as we shall see later.
  TFormattedInteger = class(TFormattedNumber)
  public
    FIntValue : Integer;
    function FormattedString : string; override;
  end;


  //This class also inherits the abstract method FormattedString from
  //TFormattedNumber. It will override the method so that the
  //sub-class will implement the functionality as we shall see later.
  TFormattedDouble = class(TFormattedNumber)
  public
    FDblValue : Double;
    function FormattedString : string; override;
  end;


  TProjectForm = class(TForm)
    Label1: TLabel;
    IntegerEntry: TEdit;
    Label2: TLabel;
    DoubleEntry: TEdit;
    DisplayButton: TButton;
    procedure DisplayButtonClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    procedure DisplayValue(FormattedNumber : TFormattedNumber);
  end;

var
  ProjectForm: TProjectForm;

implementation

{$R *.DFM}
{----------------------------------------------------------------------------------}
{ TFormattedInteger }
//This is the implementation of the overriden FormattedString
//method for our TFormattedInteger Class.
function TFormattedInteger.FormattedString : string;
begin
  Result := IntToStr(FIntValue);
end;

{----------------------------------------------------------------------------------}
{ TFormattedDouble }
//This is the implementation of the overriden FormattedString
//method for our TFormattedDouble Class.
function TFormattedDouble.FormattedString : string;
begin
  Result := FloatToStr(FDblValue);
end;

{---------------------------------------------------------------------------------}
{ TProjectForm }
//This procedure will accept any object that is a decendent
//of TFormattedNumber and will call it's overriden method.
//I have placed a TempString in here so that you can
//see what is what by using the reserved word "is".
procedure TProjectForm.DisplayValue(FormattedNumber: TFormattedNumber);
var
  TempString : string;
begin
  if FormattedNumber is TFormattedInteger then     //Am I a TFormattedInteger?
    TempString := 'FIntValue is = '
  else if FormattedNumber is TFormattedDouble then //Am I a TFormattedDouble?
    TempString := 'FDblValue is = ';

  ShowMessage(TempString + FormattedNumber.FormattedString);
end;
{----------------------------------------------------------------------------------}
//This is what actually makes it go.
//I instantiate two separate classes, one for TFormattedInteger
//and one for TFormattedDouble. I then populate their
//internal values. I then call DisplayValue.
procedure TProjectForm.DisplayButtonClick(Sender: TObject);
var
  FInt : TFormattedInteger;
  FDbl : TFormattedDouble;
begin
  {Create em}
  FInt := TFormattedInteger.Create;
  FDbl := TFormattedDouble.Create;

  {Populate em}
  FInt.FIntValue := StrToInt(IntegerEntry.Text);
  FDbl.FDblValue := StrToFloat(DoubleEntry.Text);

  {Display em}
  DisplayValue(FInt);
  DisplayValue(FDbl);

  {Free em}
  FInt.Free;
  FDbl.Free;
end;
{----------------------------------------------------------------------------------}

end.

image

posted on 2012-12-19 15:15  许小东  阅读(219)  评论(0编辑  收藏  举报