手机站
网通分站
电信主站
密 码:
用户名:
当前位置 : 主页>程序设计>delphi>列表

The Delphi Object Model (PART I)

来源:互联网 作者:西部数码 时间:2008-04-10
西部数码-全国虚拟主机10强!40余项虚拟主机管理功能,全国领先!双线多线虚拟主机南北访问畅通无阻!免费赠送企业邮局,.CN域名,自助建站480元起,免费试用7天,满意再付款! P4主机租用799元/月.月付免压金!

Example 2-5 uses virtual methods.

Example 2-5: Binding Virtual Methods

type
  TAccount = class
  public
    procedure Withdraw(Amount: Currency); virtual;
  end;
  TSavingsAccount = class(TAccount)
  public
    procedure Withdraw(Amount: Currency); override;
  end;
var
  Savings: TSavingsAccount;
  Account: TAccount;
begin
  ...
  Savings.Withdraw(1000.00);     // Calls TSavingsAccount.Withdraw
  Account := Savings;
  Account.Withdraw(1000.00);     // Calls TSavingsAccount.Withdraw

Instead of using the virtual directive, you can also use the dynamic directive. The semantics are identical, but the implementation is different. Looking up a virtual method in a VMT is fast because the compiler generates an index directly into a VMT. Looking up a dynamic method is slower. Calling a dynamic method requires a linear search of a class''''s dynamic method table (DMT). If the class does not override that method, the search continues with the DMT of the base class. The search continues with ancestor classes until TObject is reached or the method is found. The tradeoff is that in a few circumstances, dynamic methods take up less memory than virtual methods. Unless you are writing a replacement for the VCL, you should use virtual methods, not dynamic methods. See Chapter 3 for a complete explanation of how dynamic and virtual methods are implemented.

A virtual or dynamic method can be declared with the abstract directive, in which case the class does not define the method. Instead, derived classes must override that method. The C term for an abstract method is a "pure virtual method." If you call a constructor for a class that has an abstract method, the compiler issues a warning, telling you that you probably made a mistake. You probably wanted to create an instance of a derived class that overrides and implements the abstract method. A class that declares one or more abstract methods is often called an abstract class, although some people reserve that term for a class that declares only abstract methods.

TIP:
If you write an abstract class that inherits from another abstract class, you should redeclare all abstract methods with the override and abstract directives. Delphi does not require this, but common sense does. The declarations clearly inform the maintainer of the code that the methods are abstract. Otherwise, the maintainer must wonder whether the methods should have been implemented or should have remained abstract. For example:

type
  TBaseAbstract = class
    procedure Method; virtual; abstract;
  end;
  TDerivedAbstract = class(TBaseAbsract)
    procedure Method; override; abstract;
  end;
  TConcrete = class(TDerivedAbstract)
    procedure Method; override;
  end; 

A class method or constructor can also be virtual. In Delphi, class references are real entities that you can assign to variables, pass as parameters, and use as references for calling class methods. If a constructor is virtual, a class reference can have a static type of the base class, but you can assign to it a class reference for a derived class. Delphi looks up the virtual constructor in the class''''s VMT and calls the constructor for the derived class.

Methods (and other functions and procedures) can be overloaded, that is, multiple routines can have the same name, provided they take different arguments. Declare overloaded methods with the overload directive. A derived class can overload a method it inherits from a base class. In that case, only the derived class needs the overload directive. After all, the author of the base class cannot predict the future and know when other programmers might want to overload an inherited method. Without the overload directive in the derived class, the method in the derived class hides the method in the base class, as shown in Example 2-6.

Example 2-6: Overloading Methods

type
  TAuditKind = (auInternal, auExternal, auIRS, auNasty);
  TAccount = class
  public
    procedure Audit;
  end;
  TCheckingAccount = class(TAccount)
  public
    procedure Audit(Kind: TAuditKind); // Hides TAccount.Audit
  end;
  TSavingsAccount = class(TAccount)
  public
    // Can call TSavingsAccount.Audit and TAccount.Audit
    procedure Audit(Kind: TAuditKind); overload;
  end;
var
  Checking: TCheckingAccount;
  Savings: TSavingsAccount;
begin
  Checking := TCheckingAccount.Create;
  Savings := TSavingsAccount.Create;
  Checking.Audit;             // Error because TAccount.Audit is hidden
  Savings.Audit;              // Okay because Audit is overloaded
  Savings.Audit(auNasty);     // Okay
  Checking.Audit(auInternal); // Okay

Constructors

Every class has one or more constructors, possibly inherited from a base class. By convention, constructors are usually named Create, although you can use any name you like. Some constructor names start with Create, but convey additional information, such as CreateFromFile or CreateFromStream. Usually, though, the simple name Create is sufficient, and you can use method overloading to define multiple constructors with the same name. Another reason to overload the name Create is for compatibility with C Builder. C does not permit different constructor names, so you must use overloading to define multiple constructors.

文章整理:西部数码--专业提供域名注册虚拟主机服务
http://www.west263.com
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!