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
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!



