Delphi关键字和保留字

转载自:https://www.cnblogs.com/PocketZ/archive/2013/03/26/2983576.html

分类整理 Delphi 中的“关键字”和“保留字”,方便查询


“关键字”和“保留字”不做区分,一共  107  个。


{-------------------------------------------------------------------------------
  名称:【program】、【library】、【package】、【unit】

  功能:用于标识程序文件、动态链接库文件、包文件、单元文件的文件头。

        program :编译后生成 exe 文件,可以直接执行。

        library :编译后生成 dll 文件,可被其他程序调用。

        package :编译后生成 bpl 文件,可被安装到 delphi 的控件库中,从而在以后
        的开发中使用控件。

        unit :编译后生成 dcu 文件,将被编译到 exe 和 dll 文件中。
-------------------------------------------------------------------------------}


{ 空程序文件 Test.dpr }
program  Project1;
begin
end .

----------

{ 空动态链接库文件 Test.dpr }
library  Project1;
begin
end .

----------

{ 空包文件 Test.dpk }
package  Package1;
end .

----------

{ 空单元文件 Test.pas }
unit  Unit1;
interface
implementation
end .



{-------------------------------------------------------------------------------
  名称:【contains】、【requires】

  功能:与包文件相关的关键字。

        contains :用于指出某个包(package)是否包含某个文件,用 contains 引入
        的文件必须被添加到包文件中,它可以避免关键文件的引用丢失。

        requires :指出编译 package 时的必备条件。若 requires 的条件未满足,则
        不允许编译包。
-------------------------------------------------------------------------------}


package  MyPackage;
requires
   { 包需要运行在下面的环境中 }
  rtl, clx;
contains
   { 包需要用到下面的文件 }
  DB, DBMyControl;
end .



{-------------------------------------------------------------------------------
  名称:【interface】、【implementation】、【initialization】、【finalization】

  功能:与单元文件相关的关键字。

        interface :单元文件的接口部分,也用于定义接口类型。

        implementation :单元文件的实现部分。

        initialization :单元文件的初始化部分。

        finalization :单元文件的反初始化部分。
-------------------------------------------------------------------------------}


{ 单元文件结构 }
unit  Unit1;
interface
   { 引用其他单元、定义数据类型、定义过程函数、定义变量常量等 }
   { 此处定义的类型或数据对其他单元是可见的(可访问的) }
implementation
   { 引用其他单元、实现接口部分定义的类型、过程、函数的具体代码 }
   { 此处定义的类型或变量只对本单元可见 }
initialization
   { 这里编写单元被载入时所要调用的方法 }
   { 通常是初始化一些不能自动初始化的对象,也可以不用 }
   { initialization 最常用的情况是对 OLE 对象做初始化 }
finalization
   { 这里编写单元被释放时所要调用的方法 }
   { 通常是释放掉单元中不能自动释放的对象,也可以不用 }
   { finalization 最常用的情况是对 OLE 对象做反初始化 }
end .

----------

{ 定义接口类型 }
IEnumerator =  interface (IInterface)
   function  GetCurrent: TObject;
   function  MoveNext: Boolean;
   procedure  Reset;
   property  Current: TObject  read  GetCurrent;
end ;



{-------------------------------------------------------------------------------
  名称:【uses】

  功能:用于引用一个外部的单元。
        uses 语句通常放在一个单元的接口部分或实现部分。
-------------------------------------------------------------------------------}


{ 程序文件 }
program  Project1;
uses
  Forms,
  Unit1  in   'Unit1.pas'   {Form1} ;
begin
end .

----------

{ 单元文件 }
unit  Unit1;
interface
uses
  Windows, Messages, SysUtils, Variants, Classes;
implementation
uses
  StrUtrls;
end .



{-------------------------------------------------------------------------------
  名称:【type】

  功能:用于声明各种类型。
-------------------------------------------------------------------------------}


type

   { 声明接口 }
  IMyInterface =  interface
   end ;

   { 声明类指针 }
  PMyObject = ^TMyObject;
   { 声明类 }
  TMyObject =  class (TObject)
   end ;

   { 声明结构 }
  TMyRecord =  record
   end ;

   { 声明函数 }
  TMyFunc =  function (I: Integer):  string ;

   { 声明自定义类型 }
  TCol = (cItemA, cItemB, cItemC);
  TColSet =  set   of  TCol;
  TLatter =  'A'  ..  'Z' ;
  TInt = Integer;



{-------------------------------------------------------------------------------
  名称:【var】、【const】、【resourcestring】、【threadvar】、【absolute】

  功能:用于声明变量和常量
        var :声明变量,或者声明函数的参数为传址参数。

        const :声明常量,或者声明函数的参数为常量参数。

        resourcestring :声明资源字符串。

        threadvar :声明一个线程内变量,此变量仅供各个线程内部使用。如果在线程外
        初始化该变量,则初始化的内容不会被传入线程内,当线程创建时,该变量为空,
        且被认为是线程内的私有变量,与线程外的该变量互不干扰,与其它线程内的该变
        量也互不干扰。threadvar 必须声明为全局变量,然后在各个线程内使用。
        Delphi 说在线程内使用的 threadvar 必须在线程结束前手动释放其占用的空间。
        比如 S := ''; 即将字符串资源释放。关于资源释放,Delphi 没有更多解释。

        absolute :定义一个变量与另一个变量地址相同
-------------------------------------------------------------------------------}


{ 关于变量和常量的声明 }

procedure  TForm1.Button1Click(Sender: TObject);
resourcestring
   { 声明资源字符串 }
  rsButtonCaption =  '测试(&T)' ;
const
   { 声明常量 }
  conMax =  50 ;
var
   { 声明变量 }
  iNum: Integer;
  bFlag: Boolean;
begin
  Button1.Caption := rsButtonCaption;

  iNum := Random( 100 );
  bFlag := iNum >= conMax;
  Caption := IntToStr(iNum) +  ' - '  + BoolToStr(bFlag, True);
end ;

----------

{ 关于 threadvar }

unit  Form1Unit;

interface

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

type
  TForm1 =  class (TForm)
    Button1: TButton;
     procedure  Button1Click(Sender: TObject);
   private
     { Private declarations }
   public
     { Public declarations }
   end ;

var
  Form1: TForm1;

implementation

{$R   *.DFM}

{ NOTE: 将 GlobalStr 的定义由 var 改为 threadvar 来观察不同 }
var   { 线程内外共用此变量 }
// threadvar  { 线程内将创建此变量的一个副本,线程内外此变量互不干扰 }
  GlobalStr:  string ;

type
  TTLSThread =  class (TThread)
   private
    FNewStr: String;
   protected
     procedure  Execute;  override ;
   public
     constructor  Create;  overload ;
     constructor  Create( const  ANewStr: String);  overload ;
   end ;

procedure  SetShowStr( const  S: String;  const  sTitle:  string  =  '' );
begin
   if  S =  ''   then
    MessageBox( 0 , PChar(GlobalStr), PChar(sTitle), MB_OK)
   else
    GlobalStr := S;
end ;

constructor  TTLSThread.Create;
begin
   inherited  Create(False);
end ;

constructor  TTLSThread.Create( const  ANewStr: String);
begin
  FNewStr := ANewStr;
   inherited  Create(False);
end ;

procedure  TTLSThread.Execute;
begin
  FreeOnTerminate := True;
  SetShowStr(FNewStr);
  SetShowStr( '' '线程内 - 线程执行时' );
end ;

procedure  TForm1.Button1Click(Sender: TObject);
begin
  SetShowStr( '线程外的 GlobalStr 变量' );
  SetShowStr( '' '线程外 - 线程创建前' );

  TTLSThread.Create( '线程内的 GlobalStr 若为 threadvar 类型,则与线程外的 GlobalStr 无关' );
  Sleep( 100 );

  SetShowStr( '' '线程外 - 线程创建后,观察 GlobalStr 在线程内外是否不同' );
end ;

end .

----------

{ 同地址变量 }

{ 下面的代码声明了变量 ucLen 的起始地址与 ShortStrig 型变量 sStr 相同,由
  于 ShortString 的第 0 个位置保存了字符串的长度,所以 ucLen 的值即为字符
  串的长度。 }


procedure  TForm1.Button1Click(Sender: TObject);
var
  sStr:  ShortString;
  ucLen: Byte  absolute  sStr;
begin
  sStr :=  '1234567890' ;
  Caption := IntToStr(ucLen);
end ;



{-------------------------------------------------------------------------------
  名称:【begin】、【end】

  功能:begin end :组合使用,可以表示一段代码或一个程序的开始和结束。

        end 还可以与 case, class, interface, asm, unit, package 等相匹配。

        对于语句块,end 后必须添加分号。而对于单元或包,end 后必须添加句点。
在 If 语句中 else 关键字前的 end 后不允许添加分号。
-------------------------------------------------------------------------------}


{ 一段代码的开始和结束 }

procedure  TForm1.Button1Click(Sender: TObject);
var
  I: Integer;
begin
  I := Random( 100 );
   if  I <  50   then
   begin
    Caption := IntToStr(I);
   end
   else
   begin
    Caption := IntToStr(I -  50 );
   end ;
end ;

----------

{ 程序文件的开始和结束 }

program  Project1;
begin
end .

----------

{ 包文件的开始和结束,不需要 begin }

package  Package1;
end .

----------

{ 类的开始和结束,不需要 begin }

TMyObject =  class (TObject)
end ;



{-------------------------------------------------------------------------------
  名称:【if】、【then】、【else】、【case】

  功能:if then else 组合使用,构成条件判断语句,当不需要 else 时,可以省略 else
        ,当 else 与 if 配合使用时,else 前面的一条语句不能以分号结束。

        case else 组合使用,构成条件选择语句。

        else 还可以与 try except on 语句组合,构成异常处理语句,详见 except。
-------------------------------------------------------------------------------}


{ if then else(条件判断) }

procedure  TForm1.Button1Click(Sender: TObject);
var
  I: Integer;
begin
  I := Random( 100 );
   if  I <  50   then
    Caption := IntToStr(I)
   else
    Caption := IntToStr(I -  50 );
   end ;
end ;

{ if then(条件判断,无 else) }

procedure  TForm1.Button1Click(Sender: TObject);
var
  I: Integer;
begin
  I := Random( 100 );
   if  I <  50   then
    Caption := IntToStr(I);
end ;

----------

{ case else(条件选择) }

procedure  TForm1.Button1Click(Sender: TObject);
var
  I: Integer;
begin
  I := Random( 100 );
   case  I  of
     1  ..  33 :
      Caption :=  '小' ;
     34  ..  66 :
      Caption :=  '中' ;
     67  ..  99 :
      Caption :=  '大' ;
   else
    Caption :=  '0' ;
   end ;
end ;



{-------------------------------------------------------------------------------
  名称:【for】、【to】、【downto】、【do】、【while】、【repeat】、【until】

  功能:for to(或downto) do 组合使用,构成 for 循环语句。

        while do 组合,构成 while 循环语句。

        repeat until 组合,构成 repeat 循环语句。

        for 还可以与 in 组合,构成 for 循环语句,详见 in
        do 还可以与 with 组合构成默认对象语句,详见 with
        do 还可以与 try except on 组合使用,构成异常处理语句,详见 except。
-------------------------------------------------------------------------------}


{ for 循环语句,循环变量递增 }

procedure  TForm1.Button1Click(Sender: TObject);
var
  I, iSum: Integer;
begin
  iSum :=  0 ;
   for  I :=  1   to   100   do
    iSum := iSum + I;
  Caption := IntToStr(iSum);   { 结果 5050 }
end ;

{ for 循环语句,循环变量递减 }

procedure  TForm1.Button1Click(Sender: TObject);
var
  I, iSum: Integer;
begin
  iSum :=  0 ;
   for  I :=  100   downto   1   do
    iSum := iSum + I;
  Caption := IntToStr(iSum);   { 结果 5050 }
end ;

----------

{ while 语句 }

procedure  TForm1.Button1Click(Sender: TObject);
var
  I, iSum: Integer;
begin
  iSum :=  0 ;
  I :=  0 ;
   while  I <=  100   do   begin
    iSum := iSum + I;
    Inc(I);
   end ;
  Caption := IntToStr(iSum);   { 结果 5050 }
end ;

----------

{ repeat 语句 }

procedure  TForm1.Button1Click(Sender: TObject);
var
  I, iSum: Integer;
begin
  iSum :=  0 ;
  I :=  0 ;
   repeat
    iSum := iSum + I;
    Inc(I);
   until  I >  100 ;
  Caption := IntToStr(iSum);   { 结果 5050 }
end ;



{-------------------------------------------------------------------------------
  名称:【with】

  功能:用于设置默认对象,简化代码。
-------------------------------------------------------------------------------}


{ with 语句 }

procedure  TForm1.Button1Click(Sender: TObject);
begin

// 这里的 4 行代码可以用 with 语句简化输入:
// (Sender as TButton).Left := 0;
// (Sender as TButton).Top := 0;
// (Sender as TButton).Width := 120;
// (Sender as TButton).Height := 60;

   with  (Sender  as  TButton)  do
   begin
    Left :=  0 ;
    Top :=  0 ;
    Width :=  120 ;
    Height :=  60 ;
   end ;

  Caption :=  '测试 with 语句' ;
  Width := Width  div   2 ;
  Height := Height  div   2 ;
end ;



{-------------------------------------------------------------------------------
  名称:【label】、【goto】

  功能:goto  :无条件跳转
        label :定义跳转标签,goto 语句只能跳转到已定义的标签位置。
-------------------------------------------------------------------------------}


procedure  TForm1.Button1Click(Sender: TObject);
label
  AA;
var
  I, iNum: Integer;
begin
  I :=  0 ;
  iNum :=  0 ;
AA:
  inc(I);
  iNum := iNum + I;
   if  I <  10   then
     goto  AA;

  Caption := IntToStr(iNum);   { 结果 55 }
end ;



{-------------------------------------------------------------------------------
  名称:【asm】、【assembler】

  功能:asm 用于在程序中插入汇编代码。
        使用汇编代码时, 必须使用 asm ...end; 的结构,而非 begin ... end;

        assembler 用于支持早期的汇编, 如80386等。它和 asm 的区别是 asm 允许使用
        Win32 汇编, 而 assembler 只允许 80x86 汇编, 它不允许 Invoke 语句的出现。
-------------------------------------------------------------------------------}


function  IntToHex(Value: Integer; Digits: Integer):  string ;
asm
  CMP  EDX,  32
  JBE  @A1
   xor   EDX, EDX
@A1: PUSH ESI
  MOV  ESI, ESP
  SUB  ESP,  32
  PUSH ECX
  MOV  ECX,  16
  CALL CvtInt
  MOV  EDX, ESI
  POP  EAX
  CALL System.@LStrFromPCharLen
  ADD  ESP,  32
  POP  ESI
end ;



{-------------------------------------------------------------------------------
  名称:【and】、【or】、【not】、【xor】、【shl】、【shr】、【div】、【mod】

  功能:Delphi 运算符。

        and(逻辑与 或 按位与) or(逻辑或 或 按位或) not(逻辑非 或 按位否)
        xor(逻辑异或 或 按位异或) shl(位左移) shr(位右移)
        div(整除) mod(求余数)

        xor(逻辑异或 或 按位异或)我喜欢把它叫做“逻辑异”,只要 xor 两边的布尔
        值不相同(相异),结果就为 True,否则就为 False。只要 xor 两边的位状态不
        同(0 和 1 不同),结果就为 1,否则就为 0。
-------------------------------------------------------------------------------}


{ 逻辑与 }

procedure  TForm1.Button1Click(Sender: TObject);
var
  A, B: Integer;
begin
  A :=  1 ;
  B := - 1 ;
   if  (A >  0 and  (B >  0 then
    Caption :=  'True'
   else
    Caption :=  'False' ;    { 结果 False }
end ;

{ 逻辑或 }

procedure  TForm1.Button1Click(Sender: TObject);
var
  A, B: Integer;
begin
  A :=  1 ;
  B := - 1 ;
   if  (A >  0 or  (B >  0 then
    Caption :=  'True'     { 结果 True }
   else
    Caption :=  'False' ;
end ;

{ 逻辑非 }

procedure  TForm1.Button1Click(Sender: TObject);
var
  A, B: Integer;
begin
  A :=  1 ;
  B := - 1 ;
   if   not  A > B  then
    Caption :=  'True'
   else
    Caption :=  'False' ;    { 结果 False }
end ;

{ 逻辑异或 }

procedure  TForm1.Button1Click(Sender: TObject);
var
  A, B: Integer;
begin
  A :=  1 ;
  B := - 1 ;
   if  (A >  0 xor  (B >  0 then
    Caption :=  'True'    { xor 两边的布尔值不同,结果 True }
   else
    Caption :=  'False' ;
end ;

----------

{ 按位与 }

procedure  TForm1.Button1Click(Sender: TObject);
var
  A, B, C: Integer;
begin
  A :=  360 ;
  B :=  120 ;
  C := A  and  B;
  Caption := IntToStr(C);   { 结果:104 }
end ;

{ 按位或 }

procedure  TForm1.Button1Click(Sender: TObject);
var
  A, B, C: Integer;
begin
  A :=  360 ;
  B :=  120 ;
  C := A  or  B;
  Caption := IntToStr(C);   { 结果:376 }
end ;

{ 按位否 }

procedure  TForm1.Button1Click(Sender: TObject);
var
  A, C: Integer;
begin
  A :=  360 ;
  C :=  not  A;
  Caption := IntToStr(C);   { 结果:-361 }
end ;

{ 按位异或 }

procedure  TForm1.Button1Click(Sender: TObject);
var
  A, B, C: Integer;
begin
  A :=  360 ;
  B :=  120 ;
  C := A  xor  B;
  Caption := IntToStr(C);   { 结果:272 }
end ;

{ 位左移 }

procedure  TForm1.Button1Click(Sender: TObject);
var
  A, C: Integer;
begin
  A :=  360 ;
  C := A  shl   1 ;   { 相当于 A 乘以 2 的 1 次方 }
  Caption := IntToStr(C);   { 结果:720 }
end ;

{ 位右移 }

procedure  TForm1.Button1Click(Sender: TObject);
var
  A, C: Integer;
begin
  A :=  360 ;
  C := A  shr   1 ;   { 相当于 A 除以 2 的 1 次方 }
  Caption := IntToStr(C);   { 结果:180 }
end ;

----------

{ 整除 }

procedure  TForm1.Button1Click(Sender: TObject);
var
  A, B, C: Integer;
begin
  A :=  36 ;
  B :=  5 ;
  C := A  div  B;
  Caption := IntToStr(C);   { 结果:7 }
end ;

{ 求余数 }

procedure  TForm1.Button1Click(Sender: TObject);
var
  A, B, C: Integer;
begin
  A :=  36 ;
  B :=  5 ;
  C := A  mod  B;
  Caption := IntToStr(C);   { 结果:1 }
end ;



{-------------------------------------------------------------------------------
  名称:【try】、【finally】、【except】、【on】、【raise】

  功能:这些都是异常处理语句。

        try finally 组合使用,构成异常处理语句。先执行 try 部分的语句,无论 try
        部分是否执行成功,finally 部分都会被执行。

        try except on 组合使用,构成异常处理语句。正常情况下执行 try 部分的语句。
        如果发生异常,则执行 except 后的语句。

        raise 用于抛出异常。如果希望通过外部程序处理异常,或是在异常发生时重新将
        异常抛出,可以使用 raise 语句。异常被抛出后,raise 后面的代码将不被执行。
-------------------------------------------------------------------------------}


{ try finally(异常处理) }

procedure  TForm1.Button1Click(Sender: TObject);
var
  Strs: TStringList;
begin
  Strs := TStringList.Create;
   try
    Strs.Add( 'finally Test' );
    Caption := Strs[ 0 ];
   finally
    Strs.Free;
   end ;
end ;

----------

{ try except on else(异常处理) }

procedure  TForm1.Button1Click(Sender: TObject);
var
  I: Integer;
  S: String;
begin
  S :=  '123A' ;
   try
    I := StrToInt(S);
   except
     on  EZeroDivide  do
      Caption :=  'EZeroDivide' ;
     on  EOverflow  do
      Caption :=  'EOverflow' ;
     else
      Caption :=  'Unknow Error' ;
   end ;
end ;

----------

{ raise 抛出异常 }

procedure  TForm1.Button1Click(Sender: TObject);
var
  I: Integer;
begin
   { 普通代码中抛出异常 }
  I := - 1 ;
   if  I <  0   then
     raise  exception.Create( '整数不能小于 0' );
  ShowMessage( '异常被抛出后...' );
end ;

{ raise 抛出异常 }

procedure  TForm1.Button1Click(Sender: TObject);
var
  I: Integer;
  S:  string ;
begin
   { try except 中抛出异常 }
   try
    S :=  '123A' ;
    I := StrToInt(S);
   except
     on  E: exception  do
       raise  exception.Create(E.Message);
   end ;
  ShowMessage( '异常被抛出后...' );
end ;



{-------------------------------------------------------------------------------
  名称:【procedure】、【function】、【forward】、【out】

  功能:Delphi 函数、过程相关关键字。

        procedure :定义过程,过程无返回值。主要用来执行一系列动作。还可以用来声
        明自定义函数类型。

        function :定义函数,函数有返回值。主要用来计算某一结果。还可以用来声明
        自定义函数类型。

        forward :用于函数(或过程)的前置声明,这样可以使代码中“较先实现的函数
        ”可 以调用“较后实现的函数”,如果“较后实现的函数”不做前置声明,则它不
        能被前面的函数调用。

        out :定义函数(或过程)的参数为传出类型,out 类型的参数用来将函数的执行
        结果通过此参数返回给调用者(传地参数)。调用者在调用函数时,不需要给 out
        类型的参数赋值,赋了也没用。

        还有之前提到的一个关键字 var :定义函数(或过程)的参数为传址类型,var
        类型的参数在函数内的一切改变都会返回给调用者,调用者也可以在调用函数前,
        给 var 参数赋值,然后传递到函数里面使用。
-------------------------------------------------------------------------------}


{ 函数前置声明 }
function  CalcPerimeter(R: Double): Double;  forward ;
function  CalcArea(R: Double): Double;  forward ;

{ 过程:执行一系列动作,显示圆的半径、周长、面积信息 }
procedure  ShowInfo(Radius: Double);
var
  sRadius:  string ;
  sPerimeter:  string ;
  sArea:  string ;
begin
  sRadius := FloatToStr(Radius);

   { 如果不做前置声明,则这里无法调用 CalcPerimeter }
  sPerimeter := FloatToStr(CalcPerimeter(Radius));

   { 如果不做前置声明,则这里无法调用 CalcArea }
  sArea := FloatToStr(CalcArea(Radius));

  ShowMessage( '半径:'  + sRadius +  #13 #10  +
   '周长:'  +  sPerimeter +  #13 #10  +
   '面积:'  + sArea);
end ;

{ 函数:计算圆的周长 }
function  CalcPerimeter(R: Double): Double;
begin
   { 2 乘以 派 乘以 半径,Pi 是系统函数,计算圆周率 }
  Result :=  2  * Pi * R;
end ;

{ 函数:计算圆的面积 }
function  CalcArea(R: Double): Double;
begin
   { 派 乘以 半径的平方,Pi 是系统函数,计算圆周率 }
  Result := Pi * R * R;
end ;

procedure  TForm1.Button1Click(Sender: TObject);
begin
  ShowInfo( 10.5 );
  ShowInfo( 30.25 );
end ;

----------

{ 声明自定义函数类型 TMyFunc }
type
  TMyFunc =  function (I: Integer): Integer;

{ 某个函数 }
function  GetCountNum(Num: Integer): Integer;
var
  I: Integer;
begin
  Result :=  0 ;
   for  I :=  0   to  Num  do
   begin
    Result := Result + I;
   end ;
end ;

{ 这里只是简单测试,自定义函数类型一般用作函数或过程的参数 }
procedure  TForm1.Button1Click(Sender: TObject);
var
  MyFunc: TMyFunc;
  iCountNum: Integer;
begin
   { 将某个同类型的函数赋值给 MyFunc }
  MyFunc := GetCountNum;

   { 然后 MyFunc 就可以像普通函数一样使用了 }
  iCountNum := MyFunc( 100 );

  Caption := IntToStr(iCountNum);   { 结果 5050 }
end ;

----------

{ var 和 out 测试 }

{ 过程是没有返回值的,但是我们可以通过 var 或 out 参数来返回数据 }
procedure  Test( var  I: Integer;  out  S: String);
begin
   { 先看看传进来的是什么 }
  ShowMessage( '参数I:'  + IntToStr(I) +  #13 #10  +  '参数S:'  + S);   { S 将为空 }
   { 修改参数的值,看能否传递到过程外面去 }
  I := I +  100 ;
  S := S +  'AfterStr' ;   { 如果我们将这一行代码注释掉,则 S 将返回空字符串 }
end ;

procedure  TForm1.Button1Click(Sender: TObject);
var
  A: Integer;
  B: String;
begin
  A :=  1 ;
  B :=  'ABC' ;
  Test(A, B);   { 'ABC' 无法传入到函数中 }
  Caption := IntToStr(A ) +  ' '  + B;     { 结果 101 AfterStr }
end ;



{-------------------------------------------------------------------------------
  名称:【cdecl】、【pascal】、【stdcall】、【safecall】、【register】
        【varargs】

  功能:函数(或过程)的调用协定,各个调用协定的要求内容太多,这里只是简单说明,
        具体可以翻查相关资料。

        cdecl :规定了从 C 或 C++ 编写的 DLL 中调用函数所必须遵守的规则。它可以
        将 C 或 C++ 中的数据类型转换为 Delphi 的类型。

        pascal :规定参数从左向右传递。函数调用时要对所有的变量进行初始化,避免
        因异步线程调用而产生的错误,保留它是为了向下兼容。

        stdcall :规定参数从右向左传递。同时 stdcall 规定, 被调函数是大小写敏感
        的。在调用函数时,如果函数名中有一个字符的大小写出错,则该函数将调用失败。

        safecall :规定被 COM 调用的函数所必须遵守的规则。在编译时,safecall 声
        明的函数被编译成与 COM 接口兼容的。

        register :Delphi 专用的函数调用协定,直接通过寄存器传递参数,因此传递速
        度非常块。
        register 关键字也被用来注册控件。

varargs :标示了引用参数,它必须和 cdecl 关键字联用,表明允许调用的函数
使用引用传递。
-------------------------------------------------------------------------------}


{ cdecl }

// { 例如 C++ 中的代码 }
// int CFun(int i)
// {
//   return i*2;
// }

{ 如果这个函数被编译在 Test.dll 中, 则用 Delphi 调用时必须使用如下方式 }
function  CFun(i: Integer): Integer; Cdecl;  external   'Test.dll' ;

----------

{ pascal }

function  Test(I, J, K, L: Integer): Integer;  pascal ;
begin
  Result := I * J * K * L;
end ;

----------

{ stdcall }

Library Test;

function  Func1(I, J, K, L: Integer): Integer;  stdcall ;
begin
  Result := I * J * K * L;
end ;

exports
  Func1;

begin
end .

{ 主调方函数声明 }
function  Func1(I, J, K, L: Integer): Integer;  stdcall external   'Test.dll' ;

----------

{ safecall }

{ 编译时,声明函数的调用协定为 safecall 类型 }
procedure  MyFunc(S: WideString);  safecall ;

{ 编译后函数成为与 COM 接口兼容的类型 }
procedure  MyFunc(S: PAnsiString);

----------

{ register }

function  Func1(I, J, K, L: Integer): Integer;  register ;
begin
  Result := I * J * K * L;
end ;

----------

{ 注册控件 }

procedure  Register;
begin
  RegisterComponents( 'Sample' , [TTest]);
end ;

---------

{ varargs }

{ 这段代码从 C++ 的类库中引用了 Printf 函数,并允许按引用的方式传入参数 }
function  printf(Format: PChar): Integer;  cdecl ; varargs;



{-------------------------------------------------------------------------------
  名称:【class】

  功能:定义类类型,或声明一个类方法。

        具体参见 Delphi 相关资料。
-------------------------------------------------------------------------------}


{ 定义空类,默认继承自 TObject }
type
  TMyObject =  class
   end ;

----------

{ 定义 TMyObject 类并测试类方法 }
type
  TMyObject =  class (TObject)
   private
    FName:  string ;
   protected
   public
     { 定义类方法,类方法可以直接通过类调用 }
     class   procedure  ShowResult;
   published
     property  Name:  string   read  FName  write  FName;
   end ;

{ 实现类方法 }
class   procedure  TMyObject.ShowResult;
begin
  ShowMessage( '调用成功!' );
end ;

{ 调用类方法 }
procedure  TForm1.Button1Click(Sender: TObject);
begin
  TMyObject.ShowResult;   { 直接通过 TMyClass 调用,不用创建实例 }
end ;



{-------------------------------------------------------------------------------
  名称:【record】、【packed】

  功能:record :定义结构类型。

        一个结构体可以视为一个不需要实例化的类(某些地方和对象用法不同)。
        具体参见 Delphi 相关资料。

        packed :用于对结构类型对象或数组类型对象进行打包,打包后的对象体积能显著
        减小。打包后元素对齐位置也会发生变化,不再对齐到与 CPU 处理能力相匹配的位
        置,因此打包后的对象,处理速度会降低。详细信息请查阅相关资料。
-------------------------------------------------------------------------------}


{ 定义 record 类型 }
type
  TMyRec =  record
    Name:  string ;
    Age: Cardinal;
    Sex: Boolean;
   end ;

----------

{ 定义 record 类型,用法类似于 class }
type
  TMyRec =  record
   private
    FName:  string ;
   public
     procedure  ShowResult;
     property  Name:  string   read  FName  write  FName;
   end ;

{ 实现 record 方法 }
procedure  TMyRec.ShowResult;
begin
  ShowMessage( '调用成功!' );
end ;

{ 调用 record 方法 }
procedure  TForm1.Button1Click(Sender: TObject);
var
  MyRec: TMyRec;
begin
  MyRec.Name :=  'Record 测试' ;
  ShowMessage(MyRec.Name);
  MyRec.ShowResult;
end ;

----------

{ 打包 }

type
   { 未打包 }
  TMyRecA =  record
    Name:  string ;
    Age: Byte;
    Sex: Boolean;
   end ;

   { 打包 }
  TMyRecB =  packed   record
    Name:  string ;
    Age: Byte;
    Sex: Boolean;
   end ;

   { 未打包 }
  TMyArrayA =  array  [ 0  ..  32 of  Byte;

   { 打包 }
  TMyArrayB =  packed   array  [ 0  ..  32 of  Byte;

procedure  TForm1.Button1Click(Sender: TObject);
begin
  ShowMessage(IntToStr(SizeOf(TMyRecA)));
  ShowMessage(IntToStr(SizeOf(TMyRecB)));
  ShowMessage(IntToStr(SizeOf(TMyArrayA)));
  ShowMessage(IntToStr(SizeOf(TMyArrayB)));
end ;



{-------------------------------------------------------------------------------
  名称:【object】

  功能:定义对象类型,或声明“对象函数”或“对象过程”。

        定义对象类型是 Object Pascal 中的一个古老的功能,这个功能现在已经被
        class 取代。具体参见 Delphi 相关资料。
-------------------------------------------------------------------------------}


{ 定义对象 }
type
  MyObject =  object
   private
    FName:  string ;
   protected
   public
     procedure  ShowResult;
     property  Name:  string   read  FName  write  FName;
   end ;

   { 实现对象方法 }
procedure  MyObject.ShowResult;
begin
  ShowMessage( '调用成功!' );
end ;

{ 调用对象方法 }
procedure  TForm1.Button1Click(Sender: TObject);
var
   MyObj :MyObject;
begin
  MyObj.Name :=  'Object 测试' ;
  ShowMessage(MyObj.Name);
  MyObj.ShowResult;
end ;

----------

type
   { 该函数不能是独立的函数,必须是某个对象的成员 of Object }
  TMyFun =  function (I: Integer): Integer  of   object ;
   { 该过程不能是独立的过程,必须是某个对象的成员 of Object }
  TMyProc =  procedure (S:  string of   object ;



{-------------------------------------------------------------------------------
  名称:【automated】、【private】、【protected】、【public】、【published】

  功能:定义类(或结构、对象)成员的可访问类型。

        automated :自动成员,它能够使程序的版本向下兼容。
        ComObj 单元内的成员及其实例不能使用 automated 访问区分符。
        不能用于结构类型和对象类型。

        private :私有成员,只有类所在单元可以访问。

        protected :保护成员,只有子类可以访问,不能用于结构类型。

        public :公开成员,可以在任何地方被访问。

        published :发布成员,可以在运行时被访问,不能用于结构类型和对象类型。
-------------------------------------------------------------------------------}


type
  TMyObject =  class
   automated
     { 这里放置自动类型的成员 }
   private
     { 这里放置私有类型的成员 }
   protected
     { 这里放置保护类型的成员 }
   public
     { 这里放置公开类型的成员 }
   published
     { 这里放置发布类型的成员 }
   end ;

----------

{ 关于 automated }
type
  TMyObject =  class
   automated
    Str:WideString;
   end ;

{ 如果在程序的下一个版本中, 将 Str 修改成 }

type
  TMyObject =  class
   automated
    Str: AnsiString;
   end ;

{ 则新版本的 Str 变量能够接受旧版本的 WideString 型数据,并自动转换成 AnsiString。
  在实际开发中,如果没有特殊的需要,一般不用 automated 访问区分符。}




{-------------------------------------------------------------------------------
  名称:【constructor】、【destructor】、【property】

  功能:定义类类型或对象类型的构造函数,析构函数和属性。

        constructor :声明或定义一个构造函数,可以用于类类型、对象类型、结构类型。
        结构类型不允许定义无参数的构造函数。

        destructor :声明或定义一个析构函数,可以用于类类型、对象类型。
        析构函数主要用来释放对象资源。析构函数只允许覆盖,不允许重载。

        property :声明或定义一个属性,可以用于类类型、对象类型、结构类型。
        属性分为显式属性和隐式属性两种,只有声明为 published 访问类型的属性才是
        显式属性,才可以直接在对象查看器中查看。
        事件也是属性的一种,可以在 published 下用 property 进行声明。
-------------------------------------------------------------------------------}


{ 定义类类型 }
type
  TMyObj =  class (TObject)
   private
    FName:  string ;
    FAge: Cardinal;
    FOnTexChange: TEvent;   { 事件 }
   protected
   public
     { 构造函数 }
     constructor  Create;
{ 析构函数 }
destructor  Destroy;  override ;
   published
     { 发布属性 }
     property  Name:  string   read  FName  write  FName;
     property  Age: Cardinal  read  FAge  write  FAge;
     { 发布事件 }
     property  OnTextChange: TEvent  read  FOnTexChange  write  FOnTexChange;
   end ;

----------

{ 定义结构类型 }
type
  MyRec =  record
   private
    FName:  string ;
    FAge: Cardinal;
   public
     { 构造函数 }
     constructor  Create(Name:  string );
{ 不能有析构函数 }
{ 公开属性 }
     property  Age: Cardinal  read  FAge  write  FAge;
   end ;

----------

{ 定义对象类型 }
type
  MyObj =  object
   private
    FName:  string ;
    FAge: Cardinal;
   protected
   public
     { 构造函数 }
     constructor  Create;
{ 析构函数 }
destructor  Destroy;  override ;
{ 公开属性 }
     property  Name:  string   read  FName  write  FName;
     property  Age: Cardinal  read  FAge  write  FAge;
   end ;



{-------------------------------------------------------------------------------
  名称:【read】、【write】、【default】、【nodefault】
        【readonly】、【writeonly】、【stored】、【message】

  功能:定义属性的各种参数

        read :用于标识属性读取时所使用的成员或方法。

        write :用于标识属性写入时所使用的成员或方法。

        default :指示属性的默认值,或指示一个属性为类的默认属性。
        只有有序类型的属性才允许默认值的存在, 否则必须在构造函数中初始化属性值。

        nodefault :指示一个属性不允许有默认值,这通常用在继承中。

        readonly :指示一个属性为只读。
        当 readonly 设为 True 时, 不允许用户修改属性, 只能通过其他对象来操作

        writeonly :指示一个属性为只写。
        当 writeonly 设为 true 时,不允许用户读取属性,只能通过其他对象来操作

        stored :指示一个属性的值是否能被保留,若指定了True,则允许对属性值进行
        赋值撤销的操作。

        message :用于声明消息方法。
        带有 message 的方法必须指出接收的消息类型,并通过引用将消息传入方法中,
        以便进行处理。
        用户可以自定义消息,自定义消息也能够被 message 接收,并引发事件。
-------------------------------------------------------------------------------}


{ 属性的读取 }
type
  TMyObject =  class (TObject)
   private
    FValue: Integer;
   published
     { 表明 Value 属性从 FValue 成员上读出值 }
     property  Value: Integer  read  FValue;
   end ;

----------

{ 属性的写入 }
type
  TMyObject =  class (TObject)
   private
    FValue: Integer;
   published
     { 表明 Value 属性的值写入到 FValue 成员上 }
     property  Value: Integer  write  FValue;
   end ;

----------

{ 默认值和默认属性 }
type
  TMyObject =  class (TObject)
   private
    FAuto: Boolean;
    FCount: Integer;
    FNameList: TStrings;
   public
     constructor  Create;
     { 属性默认值 default True、 default 0 }
     property  Auto: Boolean  read  FAuto  write  FAuto  default  True;
     property  Count: Integer  read  FCount  write  FCount  default   0 ;
     { 默认属性 default }
     property  Names[Index: Integer]: TStrings  read  FNameList
       write  FNameList  default ;
   end ;

constructor  TMyObject.Create;
begin
   inherited ;
   { 分配对象资源 }
  FNameList := TStrings.Create;
   { 设置属性默认值 }
  FAuto := True;
end ;

----------

{ 去掉默认值 }
type
  TMyObjA =  class
   private
    FValue: Integer;
   published
     property  Value: Integer  read  FValue  write  FValue  default   0 ;
   end ;

  TMyObjB =  class (TMyObjA)
   published
     property  Value: Integer  read  FValue  write  FValue  nodefault ;
   end ;

{ 由上例可知, TMyObjA 中的 Value 有默认值 0,TMyObjB 继承了 TMyObjA,所以也继承
  了其默认值, 在此用 NoDefault 去掉默认值。 }


----------

{ 只读属性 }
property  ReadOnly;

----------

{ 只写属性 }
property  WriteOnly;

----------

{ 保留属性值 }
type
  TComponent =  class
   private
    FName: TComponentName;
   published
     property  Name: TComponentName  read  FName  write  SetName  stored  False;
   end ;

----------

{ 声明消息方法 }

unit  Form1Unit;

interface

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

type
  TForm1 =  class (TForm)
    Button1: TButton;
     procedure  Button1Click(Sender: TObject);
   private
     { Private declarations }
     procedure  Refresh( var  Msg: TMessage);  message  WM_SIZE;
   public
     { Public declarations }
   end ;

var
  Form1: TForm1;

implementation

{$R *.dfm}

{ 此方法捕捉窗口尺寸被改变的消息 }
procedure  TForm1.Refresh( var  Msg: TMessage);
begin
   { 先将窗口的尺寸显示在标题栏中 }
  Caption := IntToStr(Width) +  ' - '  +  IntToStr(Height);
   { 再调用默认消息处理函数,重绘窗口 }
   inherited ;
end ;

{ 随机调整窗口的大小 }
procedure  TForm1.Button1Click(Sender: TObject);
var
  Size: Integer;
begin
   { 先将按钮自身移到窗口左上角,以免窗口缩小后被遮挡 }
  (Sender  as  TButton).Left :=  0 ;
  (Sender  as  TButton).Top :=  0 ;

   { 获取一个随机数,可正可负 }
  Randomize;
  Size := Random( 100 ) -  50 ;
   { 设置窗口的新大小 }
  Width := Width + Size;
  Height := Height + Size;
   { 当窗口大小改变后,就会触发 WM_SIZE 消息,从而调用我们定义的 TForm1.Refresh }
end ;

end .



{-------------------------------------------------------------------------------
  名称:【array】、【file】、【set】、【string】

  功能:定义各种数据类型,或声明各种数据类型的变量。

        array :声明一个数组。

        file :声明一个文件类型。

        set :声明一个集合。

        string :声明一个字符串。
-------------------------------------------------------------------------------}


{ 定义各种数据类型 }
type
  TMyArray =  array [ 0 .. 9 of   string { 声明静态数组 }
  TCharArray =  array   of  Char;  { 声明动态数组 }
  TButtonFile =  file   of  TButton;   { 声明 TButton 格式的文件类型 }
  TIntFile =  file   of  Integer;  { 声明 Integer 格式的文件类型 }
  TLatterSet =  set   of   'A' .. 'Z' ;   { 声明大写字母集合 }
  TByteSet =  set   of  byte;   { 声明字节集合 }
  TName =  string [ 32 ];   { 声明 32 个自己长度的 ShortString 类型 }

procedure  TForm1.Button1Click(Sender: TObject);
var
   { 声明各种数据类型的变量 }
  MyArray1: TMyArray;
  MyArray2:  array   of  Char;
  MyFile1: TButtonFile;
  MyFile2:  file   of  Integer;
  MySet1: TLatterSet;
  MySet2:  set   of   'A' .. 'Z' ;
  Name1: TName;
  Name2:  string [ 255 ];
  Name3:  string ;

  I: Integer;
begin
   { 数组类型测试 }
  SetLength(MyArray2,  26 );
   for  I := Low(MyArray2)  to  High(MyArray2)  do
    MyArray2[I] := Chr( 65  + I);
  ShowMessage( string (MyArray2));

   { 集合类型测试 }
  MySet1 := [ 'A' .. 'Z' ];
  MySet2 := MySet1;
   if   'A'   in  MySet1  then  ShowMessage( 'Found A in MySet1' );
   if  CharInSet( 'A' , MySet2)  then  ShowMessage( 'Found A in MySet2' );
end ;



{-------------------------------------------------------------------------------
  名称:【in】

  功能:用于判断一个集合中是否包含某个元素。

        也可以被用在 for 语句中,用于循环取出一个集合中的元素。

        也用于工程文件中,用于标识某个文件是否被工程所引用。
-------------------------------------------------------------------------------}


procedure  TForm1.Button1Click(Sender: TObject);
var
  Item: Char;
  MySet:  set   of   'A' .. 'Z' ;
begin
   { 初始化集合 }
  MySet := [ 'A' .. 'Z' ];

   { in 用于集合 }
   if   'A'   in  MySet  then  ShowMessage( 'A is in MySet' );

   { in 用于 for 语句 }
   for  Item  in  MySet  do
    Caption := Caption + Item;
end ;

{ in 用于工程文件 }
program  Project1;
uses
  Forms,
  Unit1  in   'Unit1.pas'   {Form1} ;
begin
end .



{-------------------------------------------------------------------------------
  名称:【nil】

  功能:指示一个指针(某些对象其实也是指针)为空。
-------------------------------------------------------------------------------}


{ 检测控件是否存在 }
procedure  TForm1.Button1Click(Sender: TObject);
var
  MyEdit: TEdit;
begin
   { 仅仅释放 }
  MyEdit := TEdit.Create(Self);
   try
    MyEdit.Parent := Self;
    MyEdit.Show;
    Caption := BoolToStr(Assigned(MyEdit), True);
   finally
    MyEdit.Free;
   end ;
  ShowMessage( '控件是否存在:'  + BoolToStr(Assigned(MyEdit), True));

   { 释放并 nil }
  MyEdit := TEdit.Create(Self);
   try
    MyEdit.Parent := Self;
    MyEdit.Show;
    Caption := BoolToStr(Assigned(MyEdit), True);
   finally
    MyEdit.Free;
    MyEdit :=  nil { 这里的两行代码一般合起来写为 FreeAndNil(MyEdit) }
   end ;
  ShowMessage( '控件是否存在:'  + BoolToStr(Assigned(MyEdit), True));
end ;



{-------------------------------------------------------------------------------
  名称:【virtual】、【dynamic】、【abstract】、【inline】、【static】

  功能:指示一个类方法的类型。

        virtual :虚拟方法可以被子类覆写,虚拟方法可以加快调用速度,但浪费内存。

        dynamic :动态方法可以被子类覆写,动态方法可以节省内存,但调用速度没有虚
        拟方法快。

        abstract :抽象方法可以被子类覆写,abstract 关键字必须与 virtual 或
        dynamic 关键字同时使用。

        包含“抽象方法”的类称为“抽象类”。抽象类可以被实例化,但实例化的对象不
        能调用抽象方法,否则会抛出异常。

        inline :定义内联函数或内联汇编代码,内联函数类似于宏,编译器在编译程序
        时,会将内联函数的代码直接搬到调用者的代码里面去,作为调用者的一部分,也
        就不存在调用内联函数的说法了,直接就是一行行代码。内联函数一般是体积较小
        且被频繁调用的函数。内联函数可以提高代码的执行效率。如果没有定义内联函数
        ,则编译器会自己判断将那些函数作为内联函数处理,以便提高程序的执行效率,
        所以一般情况下我们不需要手动指定内联函数。内联说明对于编译器来说只是一种
        建议,编译器可以忽略这个建议,如果我们指定了内联函数而编译器觉得不合适,
        那么编译器可以拒绝将指定的函数内联。
        内联函数不是纯粹的函数,因此不能递归调用。
-------------------------------------------------------------------------------}


{ 虚拟方法 }
TObject =  class
public
   procedure  Dispatch( var  Message);  virtual ;
   destructor  Destroy;  virtual ;
end ;

----------

{ 动态方法 }
TCustomForm =  class
protected
   procedure  DoHide;  dynamic ;
   procedure  DoShow;  dynamic ;
end ;

----------

{ TStrings 中的抽象方法 }
TStrings =  class
protected
   { 这里只需要定义,具体功能靠子类去实现 }
   function  Get(Index: Integer):  string virtual abstract ;
   { 这里只需要定义,具体功能靠子类去实现 }
   function  GetCount: Integer;  virtual abstract ;
end ;

----------

{ 测试抽象方法 Delphi XE2 }
type

   { 定义一个抽象方法 }
  TMyObject =  class (TObject)
   public
     procedure  Test1;
     procedure  Test2;  virtual abstract ;
   end ;

procedure  TMyObject.Test1;
begin
  ShowMessage( 'Test1 OK' );
end ;

procedure  TForm1.Button1Click(Sender: TObject);
var
  MyObj: TMyObject;
begin
  MyObj := TMyObject.Create;
   try
    MyObj.Test1;
    MyObj.Test2;
     { 此处调用了抽象方法 MyObj.Test,运行时将会抛出异常 }
     { 后面的代码将不被执行 }
    Caption :=  '测试抽象方法' ;
   finally
    MyObj.Free;
   end ;
end ;

----------

{ 内联函数 }
function  Test(S:  string ):  string inline ;
begin
  Result :=  '显示结果:'  + S;
end ;

procedure  TForm1.Button1Click(Sender: TObject);
begin
  Caption := Test(Caption);
   { 此处调用了内联函数,所以,在编译时,此处的代码就被改成了
    Caption := '显示结果:' + Caption;
    直接将内联函数的代码搬过来进行编译 }

end ;



{-------------------------------------------------------------------------------
  名称:【override】、【overload】、【reintroduce】、【inherited】

  功能:override :指示子类覆写父类的一个 virtual 或 dynamic 方法。覆盖时必须沿
        用被覆盖方法的声明,并且不允许修改原方法的参数和返回类型。

        overload :指示重载一个同名函数、过程或方法。重载的同名方法时,必须具备
        “参数、类型或顺序不同”的条件。调用重载方法时,根据输入的参数不同来调用
        不同的重载方法。

        reintroduce :指示重新发布父类的方法。如果要覆盖的方法是静态方法,或是需
        要修改方法的参数等,必须用 reintroduce 进行重发布。对于 virtual 或
        dynamic 方法,可以直接用 override 进行覆盖。

        inherited :调用父类的方法。
-------------------------------------------------------------------------------}


{ 覆写父类的方法 }
type

{ 父类定义三个方法,其中两个可以被覆写,一个抽象方法 }
TMyObjectA =  class (TObject)
protected
   procedure  Test1;  virtual ;
public
   function  Test2:  string dynamic abstract ;
   function  Test3: Integer;
end ;

{ 子类继承父类的三个,同时将其中两个改写 }
TMyObjectB =  class (TMyObjectA)
protected
   procedure  Test1;  override ;
public
   function  Test2:  string override ;
end ;

{ 父类 - 方法1}
procedure  TMyObjectA.Test1;
begin
  ShowMessage( 'A' );
end ;

{ 父类 - 方法2 }
{ 抽象方法只定义,不实现 }

{ 父类 - 方法3 }
function  TMyObjectA.Test3: Integer;
begin
  Result :=  1 ;
end ;

{ 子类 - 重写方法1 }
procedure  TMyObjectB.Test1;
begin
  ShowMessage( 'B' );
end ;

{ 子类 - 重写方法2 }
function  TMyObjectB.Test2:  string ;
begin
  Result :=  'B' ;
end ;

{ 调用各个方法 }
procedure  TForm1.Button1Click(Sender: TObject);
var
  MyObjB: TMyObjectB;
begin
   { 测试子类 }
  MyObjB := TMyObjectB.Create;
   try
    MyObjB.Test1;
    Caption := MyObjB.Test2 + IntToStr(MyObjB.Test3);
   finally
    MyObjB.Free;
   end ;
end ;

----------

{ 重载函数 }

function  ShowInfo(Info: Boolean):  string overload ;
begin
  ShowMessage(BoolToStr(Info, True));
end ;

function  ShowInfo(Info: Integer):  string overload ;
begin
  ShowMessage(IntToStr(Info));
end ;

function  ShowInfo(Info:  string ):  string overload ;
begin
  ShowMessage(Info);
end ;

procedure  TForm1.Button1Click(Sender: TObject);
begin
  ShowInfo( '你好吗?' );
  ShowInfo( 123 );
  ShowInfo(True);
end ;

----------

{ 重新发布父类的方法 }

type
   { 父类 }
  TMyObjectA =  class
     procedure  Test;
   end ;

   { 子类 }
  TMyObjectB =  class (TMyObjectA)
     procedure  Test;  reintroduce ;
   end ;

   { 孙类 }
  TMyObjectC =  class (TMyObjectB)
     procedure  Test(I: Integer);  reintroduce ;
   end ;

----------

{ 调用父类方法 }

type
   { 父类 }
  TMyObjectA =  class (TObject)
   public
     procedure  Test1;  virtual ;
     procedure  Test2;  virtual ;
   end ;

   { 子类 }
  TMyObjectB =  class (TMyObjectA)
   public
     procedure  Test1;  override ;
   end ;

{ 父类 - 虚拟方法1 }
procedure  TMyObjectA.Test1;
begin
  ShowMessage( '父类方法 1' );
end ;

{ 父类 - 虚拟方法2 }
procedure  TMyObjectA.Test2;
begin
  ShowMessage( '父类方法 2' );
end ;

{ 子类 - 覆写父类方法1 }
procedure  TMyObjectB.Test1;
begin
   { 调用父类方法中的同名方法,即 Test1 }
   inherited ;
   { 调用父类方法中的 Test2 }
   inherited  Test2;
  ShowMessage( '子类方法 1' );
end ;

procedure  TForm1.Button1Click(Sender: TObject);
var
  MyObjB: TMyObjectB;
begin
  MyObjB := TMyObjectB.Create;
   try
    MyObjB.Test1;
   finally
    MyObjB.Free;
   end ;
end ;



{-------------------------------------------------------------------------------
  名称:【of】、【as】、【is】

  功能:of :用于和其他关键字构成指定的结构。
        of可以与 case, class, array, file, set, object 连用。

        as :用于将一个类对象当作另一种类型使用。

        is :用于判断对象是否属于某一类型。
-------------------------------------------------------------------------------}


{ of 关键字 }

type
  TMyClass =  class   of  TEdit;
  TMyFun =  function (I: Integer): Integer  of  Object;

procedure  TForm1.Button1Click(Sender: TObject);
var
  MyArr    :  array   of  Integer;
  MyFile   :  file   of  Byte;
  MySet    :  set   of   'A'  ..  'Z' ;
  MyClass  : TMyClass;
  MyFunc   : TMyFun;
begin
   case  Self.Tag  of
     0 :
      Caption :=  'Tag Zero' ;
   else
    Caption :=  'Tag No Zero' ;
   end ;
end ;

----------

{ as 关键字 }

procedure  TForm1.Button1Click(Sender: TObject);
begin
   { Sender 本来是 TObject 类型,现在当作 TButton 类型使用 }
  (Sender  as  TButton).Caption :=  '测试 as'
end ;

----------

{ is 关键字 }

procedure  TForm1.Button1Click(Sender: TObject);
begin
   { 显然 Sender 与 TForm 无关 }
   if  Sender  is  TForm  then  ShowMessage( 'Sender is TForm' );

   { Sender 就是 TButton }
   if  Sender  is  TButton  then  ShowMessage( 'Sender is TButton' );
   { Sender 继承自 TCustomButton }
   if  Sender  is  TCustomButton  then  ShowMessage( 'Sender is TCustomButton' );
   { Sender 继承自 TObject }
   if  Sender  is  TObject  then  ShowMessage( 'Sender is TObject' );
end ;



{-------------------------------------------------------------------------------
  名称:【implements】

  功能:implements :指出了一个属性从接口继承,此时属性被转换成接口对象。通过接口
        动态绑定属性,并动态的设定属性值。

        还有之前提到的一个关键字 Interface:用于声明一个接口类型。
-------------------------------------------------------------------------------}


{ implements }

type
  IMyInterface =  interface
     procedure  P1;
     procedure  P2;
   end ;

  TMyImplclass =  class
     procedure  P1;
     procedure  P2;
   end ;

  TMyclass =  class (TInterfacedObject, IMyInterface)
    FMyImplClass: TMyImplclass;
     property  MyImplClass: TMyImplclass  read  FMyImplClass
       implements  IMyInterface;
     procedure  IMyInterface.P1 = MyP1;
     procedure  MyP1;
   end ;

   // 通过implements声明后, 可以在类声明时指出接口中方法的实体, 如上例中的:
   // procedure IMyInterface.P1 = MyP1;

----------

{ Interface 接口类型声明 }

type
  IMalloc =  interface (IInterface)
  [ '{00000002-0000-0000-C000-000000000046}' ]
     function  Alloc(Size: Integer): Pointer;  stdcall ;
     function  Realloc(P: Pointer; Size: Integer): Pointer;  stdcall ;
     procedure  Free(P: Pointer);  stdcall ;
     function  GetSize(P: Pointer): Integer;  stdcall ;
     function  DidAlloc(P: Pointer): Integer;  stdcall ;
     procedure  HeapMinimize;  stdcall ;
   end ;



{-------------------------------------------------------------------------------
  名称:【index】、【near】、【far】、【export】、【exports】
        【external】、【name】、【resident】

  功能:index :用于在属性中标识序号,以便用相同的属性方法(Get,Set)对不同的属
        性进行操作。index 关键字也用于在属性中指出多个元素。

near :标明函数的调用协定,指出函数可以被本地调用。其他程序可以用 dll 的
        形式调用程序内的函数,保留它是为了向下兼容。

        far :标明了函数调用协定,指出函数可以被远程调用。其他程序可以用 dll 的
        形式调用程序内的函数,保留它是为了向下兼容。

export :明函数的调用协定,指出函数可以被输出,输出的函数能被本地或远程
        调用。其他程序可以用 dll 的形式调用程序内的函数,保留它是为了向下兼容。

        exports :用于输出对象,它必须被用在接口和实现之间,可以同时输出多个项,
        项与项之间用逗号分开。

        external :用于引用一个外部的或是 OBJ 内的方法。使用 external 关键字时,
        代码必须注意大小写,否则将出现错误。

name :用于指出方法的别名,对于一个要被外部引用的方法,建议用 name 申请
        方法别名,以避免外部程序改动方法的实体内容。从外部引用一个方法时,如果该
        方法有别名,则必须用 name 进行标识。

        resident :使用 resident,则当 DLLs 装入时,特定的输出信息始终保持在内
        存中。这样当其它应用程序调用该过程时,可以比利用名字扫描 DLL 入口降低时
        间开销。对于那些其它应用程序常常要调用的过程或函数,使用 resident 指示是
        合适的。这个关键字已经被废弃不用了。
-------------------------------------------------------------------------------}


{ index:属性序号 }

type
  TMyObject =  class (TObject)
   private
    FLeft: Integer;
    FTop: Integer;
    FWidth: Integer;
    FHeight: Integer;
     function  GetInfo( const  Index: Integer): Longint;
     procedure  SetInfo( const  Index: Integer;  const  Value: Longint);
   public
     property  iLeft: Longint  index   0   read  GetInfo  write  SetInfo;
     property  iTop: Longint  index   1   read  GetInfo  write  SetInfo;
     property  iWidth: Longint  index   2   read  GetInfo  write  SetInfo;
     property  iHeight: Longint  index   3   read  GetInfo  write  SetInfo;
   end ;

function  TMyObject.GetInfo( const  Index: Integer): Longint;
begin
   case  Index  of
     0 :
      Result := FLeft;
     1 :
      Result := FTop;
     2 :
      Result := FWidth;
     3 :
      Result :=FHeight;
   end ;
end ;

procedure  TMyObject.SetInfo( const  Index: Integer;  const  Value: Longint);
begin
   case  Index  of
     0 :
      FLeft := Value;
     1 :
      FTop := Value;
     2 :
      FWidth := Value;
     3 :
      FHeight :=Value;
   end ;
end ;

----------

{ index:属性的多个元素 }

type
  TMyObject =  class (TObject)
   private
    FList: TStringList;
     function  GetItem(Index: Integer):  string ;
     procedure  SetItem(Index: Integer;  const  Value:  string );
   public
     constructor  Create;
     destructor  Destroy;  override ;
     property  Items[Index: Integer]:  string   read  GetItem  write  SetItem;
   end ;

constructor  TMyObject.Create;
begin
   inherited ;
  FList := TStringList.Create;
  FList.Add( '星期一' );
  FList.Add( '星期二' );
  FList.Add( '星期三' );
  FList.Add( '星期四' );
  FList.Add( '星期五' );
  FList.Add( '星期六' );
  FList.Add( '星期日' );
end ;

destructor  TMyObject.Destroy;
begin
  FList.Free;
   inherited ;
end ;

function  TMyObject.GetItem(Index: Integer):  string ;
begin

   if  (Index >=  0 and  (Index <= (FList.Count -  1 ))  then
    Result := FList[Index]
   else
    Result :=  'Out of Index' ;
end ;

procedure  TMyObject.SetItem(Index: Integer;  const  Value:  string );
begin
   if  (Index >=  0 and  (Index <= (FList.Count -  1 ))  then
    FList[Index] := Value;
end ;

procedure  TForm1.Button1Click(Sender: TObject);
var
  I: Integer;
  MyObj: TMyObject;
begin
  MyObj := TMyObject.Create;
   try
    Caption := MyObj.Items[ 2 ];
    MyObj.Items[ 2 ] :=  'Wednesday' ;
     for  I :=  0   to   6   do
      ShowMessage(MyObj.Items[I]);
   finally
    MyObj.Free;
   end ;
end ;

----------

{ near }

function  Add(A, B: Integer): Integer;  near ;
{ 如果这个程序被编译为 Test.exe,并且另一个处于本地的程序需要调用这个函数,可以
  使用以下语句 }

function  Add(A, B: Integer): Integer;  stdcall external   'Test.exe' ;

----------
{ far }

function  Add(a,b: Integer): Integer;  far ;
{ 如果这个程序被编译为 Test.exe, 并且另一个处于其他计算机的程序需要调用这个函
  数, 可以使用以下语句 }

function  Add(a,b: Integer): Integer;  stdcall external   'Test.exe' ;

----------

{ export }

function  Add(a,b: Integer): Integer;  export ;
{ 如果这个程序被编译为 Test.exe, 而另一个程序需要调用这个函数,可以使用以下语句 }
function  Add(a,b: Integer): Integer;  stdcall external   'Test.exe' ;

----------

{ exports }

library  Test;

function  TestFunc(I: Integer):  string stdcall ;
begin
  Result := IntToStr(I);
end ;

exports  TestFunc;

begin

end .

{ 如果输出的对象被重载,则必须给对象起个别名,并注明参数 }

library  Test;

function  TestFunc(I: Integer):  string overload stdcall ;
begin
  Result := IntToStr(I); 
end ;

function  TestFunc(S:  string ): Integer;  overload stdcall ;
begin
  Result := StrToInt(S);
end ;

exports
  TestFunc(I: Integer)  name   'TestFunc1' ,
  TestFunc(S:  string )   name   'TestFunc2' ;

begin

end .

----------

{ external }

{$L Test.OBJ}
procedure  TestFunc(I:Integer);  external ;

{ 如果是从 dll 或外部程序中引用,则可以使用以下代码 }
function  TestFunc(FileName:  string ):  string external   'Test.dll' ;

{ 如果被引用的函数被重载,则必须另外指出引用的名称 }
function  MyFunc1(Code: Integer):  string overload stdcall external   'Test.dll'   name   'TestFunc1' ;
function  MyFunc2(Name:  string ): Integer;  overload stdcall external   'Test.dll'   name   'TestFunc2' ;

----------

{ name }

function  MessageBox(HWnd: Integer; Text, Caption: PChar; Flags: Integer)
  : Integer;  stdcall external   'user32.dll'   name   'MessageBoxA' ;

----------

{ resident }

function  Test:  string ;
exports  Test  name   'MyTest'   resident ;
编译时会给出警告:Symbol  'RESIDENT'   is  deprecated



{-------------------------------------------------------------------------------
  名称:【dispinterface】、【dispid】

  功能:Microsoft 专用。

        dispinterface :用于声明一个特定的适配器接口, 这个适配器能够接受标准系统
        接口中传入传出的数据。用 DispInterface 声明的接口不能被继承,只能够被引
        用。DispInterface 方法只能调用,并且必须被动态绑定。可以通过 DispId 为接
        口内方法分配适配序号。DispInterface 仅能用于 Windows 平台, 如果在 Linux
        下进行开发, 则此关键字会自动被系统屏蔽。

        dispid :DispInterface 接口中,用于指定特定的适配序号。在 DispInterface
        接口中, 适配序号必须是唯一的。如果不指定 DispId,则系统会自动分配适配序号
        给接口内每一个方法,可以通过适配序号访问 DispInterface 接口中的方法。
-------------------------------------------------------------------------------}


{ dispinterface }

{ 通常情况下,不使用 DispInterface }

----------

{ dispid }

type
  IStringsDisp =  dispinterface
    [ '{EE05DFE2-5549-11D0-9EA9-0020AF3D82DA}' ]
     property  ControlDefault[Index: Integer]: Olevariant  dispid   0 default ;
     function  Count: Integer;  dispid   1 ;
     property  Item[Index: Integer]: Olevariant  dispid   2 ;
     procedure  Remove(Index: Integer);  dispid   3 ;
     procedure  Clear;  dispid   4 ;
     function  Add(Item: Olevariant): Integer;  dispid   5 ;
     function  _NewEnum: IUnknown;  dispid  -  4 ;
   end ;
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值