I don't have a version recent enough to answer your question directly, but keep in mind that it doesn't really matter whether the class is abstract. All that does is make the compiler stop you from calling a constructor directly on the class. If you put the class reference into a class-reference variable, the compiler will allow you to call the constructor on the variable, and at run time you'll have an instance of the supposedly uninstantiable class.
var
c: TClass;
o: TObject;
begin
c := TMyAbstractClass;
o := c.Create;
Assert(o is TMyAbstractClass);
end;
What's really important is whether the class has any abstract methods. You can check for that fairly easily. Look in the class's VMT. Any virtual-method slot that contains a pointer to System._AbstractError
is an abstract method. The tricky part is knowing how many virtual-method slots to check, since that isn't recorded. Allen Bauer demonstrated how to do that in an answer to another question, but in the comments Mason Wheeler points out that it may return larger values than it should. He mentions the GetVirtualMethodCount
function from the JCL, which should give a more accurate count of user-defined virtual methods. Using that function and GetVirtualMethod
, also from the JCL, we get this function:
function HasAbstractMethods(c: TClass): Boolean;
var
i: Integer;
begin
Result := True;
for i := 0 to Pred(GetVirtualMethodCount(c)) do
if GetVirtualMethod(c, i) = @_AbstractError then
exit;
Result := False;
end;
If an abstract class has no abstract methods, then how abstract can it really be? It must have been marked abstract to prevent developers from creating instances of it, but if you really want to, you can create instances of it anyway, so marking an abstract class is really more of a warning than any actual restriction on usage.