Delphi:
abstract, override
Delphi for Win32 supports abstract class members using the abstract keyword. You can even instantiate instances of a class that contains abstract members. Then you override each abstract member in a descendant class with Override.
Delphi does not support setting an entire class as abstract. You can create an abstract class (a class with one or more abstract methods), but there is no way to tell the compiler to not allow the instantiation of the abstract class.
Delphi does not support abstract member properties directly. To implement an abstract properity, make use of abstract methods. That is, you can read a GetPropertyX abstract function and write to a SetPropertyX abstract procedure. In effect, creating an abstract property.
Syntax Example:TCyborg = class(TObject) public procedure Speak(pMessage: String); virtual; abstract; procedure Walk; virtual; abstract; end; TSeries600 = class(TCyborg) public procedure Speak(pMessage: String); override; procedure Walk; override; end;
|
Now let's dig deeper...
Virtual Abstract versus Dynamic Abstract
For abstract methods, you must specify either regular virtual with the virtual keyword or dynamic virtual with the dynamic keyword. In Delphi for Win32, virtual methods are optimized for speed and dynamic methods are optimized for size. The Delphi help indicates to use virtual for most situations.
It is true that the compiler could make virtual the default and therefore optional but requiring one or the other is consistent with Object Pascal's strong typing. However, with Delphi Prism, the use of the virtual keyword with abstract methods is optional.
An Abstract Example with an Abstract Property
The following demonstrates the abstract method above and also contains an abstract property (or rather, a regular property that makes use of an abstract method). The following form unit assumes a form with a button. unit AbstractionUnit; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); end; TCyborg = class(TObject) private FCyborgName: String; protected procedure SetCyborgName(const Value: String); virtual; abstract; public property CyborgName: String read FCyborgName write SetCyborgName; procedure Speak(pMessage: String); virtual; abstract; procedure Walk; virtual; abstract; end; TSeries600 = class(TCyborg) protected procedure SetCyborgName(const Value: String); override; public procedure Speak(pMessage: String); override; procedure Walk; override; end; var Form1: TForm1; implementation {$R *.dfm} procedure TSeries600.Speak(pMessage: String); begin ShowMessage(pMessage); end; procedure TSeries600.SetCyborgName(const Value: String); begin FCyborgName := Value; end; procedure TSeries600.Walk; begin //Implement here. end; procedure TForm1.Button1Click(Sender: TObject); var MyKiller: TSeries600; begin MyKiller := TSeries600.Create; MyKiller.CyborgName := 'John'; MyKiller.Speak('I am ' + MyKiller.CyborgName + '.'); MyKiller.Speak('I''ll be back.'); end; end.
Summary
Abstraction is an important aspect of your software design. To learn more about how abstract classes are similar concepts to interfaces, how they relate to Plato's Forms theory, and more, read our Abstract Members / Class definition article next.
More Info
|