DN4DP#27: .NET vs Win32: Abstract classes
This post continues the series of The Delphi Language Chapter teasers from Jon Shemitz’ .NET 2.0 for Delphi Programmers book.
Last time we looked at initialization and finalization sections. This post covers some minor differences in abstract class behavior.
Note that I do not get any royalties from the book and I highly recommend that you get your own copy – for instance at Amazon.
"Abstract classes
The concept of abstract classes is strictly enforced by the CLR runtime – it will not allow you to instantiate instances of abstract classes or classes containing abstract methods. In Win32 you can create instances of classes containing abstract methods. Normally you will get a compiler warning, though – this warning has been turned into a compiler error in .NET.
When creating instances through a class of reference, the compiler’s static checking cannot prevent you from compiling code that could potentially instantiate abstract classes. In Win32 this will go undetected at runtime, unless you actually call an abstract method – then you will get an EAbstractError exception. In .NET, the runtime will raise an exception if you try to call the constructor of an abstract class. The AbstractClasses project demonstrates these differences.
Code Sample
unit AbstractClassesU;
interface
type
TFoo = class
procedure Bar; virtual; abstract;
constructor Create; virtual;
constructor Create2;
end;
TFooClass = class of TFoo;
TBar = class(TFoo)
procedure Bar; override;
constructor Create; override;
end;
procedure Test;
implementation
var
Foo: TFoo;
FooClass: TFooClass;
{ TFoo }
constructor TFoo.Create;
begin
inherited Create;
writeln('TFoo.Create');
end;
constructor TFoo.Create2;
begin
inherited Create;
writeln('TFoo.Create2');
end;
{ TBar }
constructor TBar.Create;
begin
inherited Create;
writeln('TBar.Create');
end;
procedure TBar.Bar;
begin
writeln('TBar.Bar');
end;
{$DEFINE TEST_ERRORS}
{$IFDEF TEST_ERRORS}
procedure TestErrors;
begin
// Direct creation of class with abstract method
Foo := TFoo.Create; // Win32 Warning / .NET error
// Call of abstract method
Foo.Bar; // Win32 run-time exception
// Calling non-virtual constructor through class reference
FooClass := TBar;
Foo := FooClass.Create2; // .NET compile-time error
// Creation of abstract class via class reference
FooClass := TFoo;
Foo := FooClass.Create; // .NET run-time error
// Call of abstract method
Foo.Bar; // Win32 run-time error
end;
{$ENDIF}
procedure TestOK;
begin
// Creation of concrete class via class reference
FooClass := TBar;
Foo := FooClass.Create;
Foo.Bar;
writeln('OK');
end;
procedure Test;
begin
TestOK;
{$IFDEF TEST_ERRORS}
TestErrors;
{$ENDIF}
end;
end.
"
No comments:
Post a Comment