Reputation: 35
I'd like to create a class or interface that I could subclass, always using current class instances as methods parameters...
Here is an example to explain my problem:
type IArithmeticObject = interface(IInterface)
procedure assign(ao : IArithmeticObject);
procedure add(ao : IArithmeticObject);
procedure remove(ao : IArithmeticObject);
procedure multiply(ao : IArithmeticObject);
procedure divide(ao : IArithmeticObject);
end;
the interface IArithmeticObject
whould be the starting point, referencing basic arithmetic operations and child classes could be declared as
type TInteger = class(TInterfacedObject, IArithmeticObject)
procedure assign(ao : TInteger);
procedure add(ao : TInteger);
procedure remove(ao : TInteger);
procedure multiply(ao : TInteger);
procedure divide(ao : TInteger);
end;
with parameter type for ao
being TInteger
and not IArithmeticObject
.
Another idea would be to use a self referencing generic type like:
AMathObject = class;
AMathObject<T : AMathObject, constructor> = class
procedure assign(ao : T);virtual;abstract;
procedure add(ao : T);virtual;abstract;
procedure remove(ao : T);virtual;abstract;
procedure multiply(ao : T);overload;virtual;abstract;
procedure divide(ao : T);virtual;abstract;
end;
but I could not figure out the right syntax...
Does anyone have any ideas about this possibility (or impossibility)?
Upvotes: 2
Views: 1074
Reputation: 4878
If I undestand it correctly, you may want to derive your class from a generic interface.
type
IArithmeticObject<T> = interface
procedure assign(ao: IArithmeticObject<T>);
procedure add(ao: IArithmeticObject<T>);
procedure remove(ao: IArithmeticObject<T>);
procedure multiply(ao: IArithmeticObject<T>);
procedure divide(ao: IArithmeticObject<T>);
end;
TInteger = class (TInterfacedObject, IArithmeticObject<TInteger>)
procedure assign(ao: IArithmeticObject<TInteger>);
procedure add(ao: IArithmeticObject<TInteger>);
procedure remove(ao: IArithmeticObject<TInteger>);
procedure multiply(ao: IArithmeticObject<TInteger>);
procedure divide(ao: IArithmeticObject<TInteger>);
end;
Answer edited according to the Stefan Glienke's comment: now the methods of the class accept parameters declared either as objects or interfaces.
var
ao: IArithmeticObject<TInteger>;
begin
ao := TInteger.Create;
ao.multiply(ao);
end.
Upvotes: 3