There are 3 ways to solve this problem:
1) Interfaces. Problem with this method - extra layer of abstraction, you need to describe - interfaces. They can be treated as abstract classes, that are used to provide access to your classes. In many cases it's done anyway. For example when implementations of classes are separated to DLL. Interfaces are still limited. While one class can implement several interfaces, inheritance between several classes and between several interfaces still has to be single. I.e. if several classes implement several interfaces to one object - they have to be inherited from each other. Otherwise you would need to use class composition and "implements" directive anyway. Interfaces support virtual runtime casting though. I.e. one interface can be casted to any other interface, implemented by the same object, even if one isn't inherited from another.
TSuperClass = interface;
TSuperClassImplementation = class(TInterfacedObject, TSuperClass);
TSubClassImplementation1 = class(TSuperClassImplementation)
//Implement your Method 1 here
end;
TSubClassImplementation2 = class(TSuperClassImplementation)
//Implement your Method 2 here
end;
//etc.
var
MyObject:TSuperClass;
MyObject := TSubClassImplementation1.Create;
2) Class composition. As powerful, as multiple inheritance, but is very clunky. You have to do everything manually. I.e. store references to method implementing objects, create them, destroy, etc.
//First variant
TAbstractMethodImplementation = class;
//Second variant
TMethod = procedure of object;
TMethodImplementation1 = class(TAbstractMethodImplementation);
TMethodImplementation2 = class(TAbstractMethodImplementation);
TMethodImplementation3 = class(TAbstractMethodImplementation);
TSuperClass = class
protected
FMethodImplementation:TAbstractMethodImplementation;
//For second variant, use FMethod := FMethodImplementation.MyMethod
FMethod:TMethod;
public
procedure MyMethod;
end;
//Yeah, clunky stubs are needed
procedure TSuperClass.MyMethod;
begin
FMethodImplementation.MyMethod;
//Second variant
//Just call FMethod;
end;
TSupClass1 = class(TSuperClass)
constructor Create;
end;
constructor TSupClass1.Create;
begin
FMethodImplementation := TMethodImplementation1.Create;
end;
3) Multiple inheritance (not supported by FPC/Lazarus). Very powerful, but has complications and considered to be overkill, that should be avoided. Just syntax sugar around static objects (i.e. TP-style objects, virtual methods are little bit more complex though). But I personally think, that it's pros are >> than it's cons. One line of code "late binding" - is very powerful thing. Just one line of code allows you to assemble complex class from many different parts, while their code is 100% shared.
TInterfaceWithOtherClasses = class;
TAbstractMethodImplementation = class(TInterfaceWithOtherClasses:virtual);
TMethodImplementation1 = class(TAbstractMethodImplementation);
TMethodImplementation2 = class(TAbstractMethodImplementation);
TMethodImplementation3 = class(TAbstractMethodImplementation);
TSuperClass = class(TInterfaceWithOtherClasses:virtual);
//FULL POWER OF MULTIPLE INHERITANCE IN JUST ONE LINE OF CODE!!!
TSubClass1 = class(TSuperClass, TMethodImplementation1:override);