Recent

Author Topic: Representing Methods in different Classes  (Read 2633 times)

MarkMLl

  • Hero Member
  • *****
  • Posts: 3526
Re: Representing Methods in different Classes
« Reply #15 on: October 20, 2021, 02:57:40 pm »
Make a class "Part", implement one for "Damper" and one for "Motor", add a list of Parts to the main class.

Yes, that would probably work.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

Weitentaaal

  • Sr. Member
  • ****
  • Posts: 328
  • Weitental is a very beautiful garbage depot.
Re: Representing Methods in different Classes
« Reply #16 on: October 20, 2021, 03:08:36 pm »
but i have all variables in my subclass, which means i would have to hand over like 20 params and that just for 1 single Method.
Same with Results.

Put them in a record, or an instance of a class.

MarkMLl


I will try it out !

Make a class "Part", implement one for "Damper" and one for "Motor", add a list of Parts to the main class.

With these 2 solutions i will be able to solve it i guess. If not i will update this Post.

Thanks Guys :)
Lazarus: 2.0.12 x86_64-win64-win32/win64
Compiler Version: 3.2.0

Mr.Madguy

  • Hero Member
  • *****
  • Posts: 737
Re: Representing Methods in different Classes
« Reply #17 on: October 21, 2021, 06:06:53 am »
It's usually done this way:

TSubClass1 (TSuperClass )
TSubClass2 (TSuperClass )
TSuperClass2(TSuperClass) - implements shared method
TSubClass3 (TSuperClass2) \
TSubClass4 (TSuperClass2)  |> this three Classes should have a shared Method.
TSubClass5 (TSuperClass2) /

But true "late binding" can be achieved via multiple inheritance only. Pascal supports limited version of multiple inheritance via interfaces.
24.11.2021 - DynamicData 4.0 runtime is overhauled to improve scalability.
My project still requires full Delphi 2009 support to be ported to Lazarus.
It's time to finally do it, because Delphi 2009 is 12 years old.

egsuh

  • Hero Member
  • *****
  • Posts: 862
Re: Representing Methods in different Classes
« Reply #18 on: October 22, 2021, 09:48:16 am »

Try procedural types.  I'm adding to your original codes. I haven't tested following codes myself^^.

Code: Pascal  [Select][+][-]
  1. program TestProg;
  2.  
  3. Uses Classes, SysUtils;
  4.  
  5. Type
  6.  
  7.    TThisAndThat = procedure (i1, i2, i3: integer) of object;
  8.    TSomeThingElse = function (i: integer; d: double): double of object;
  9.  
  10.   { TSuperClass }
  11.  
  12.   TSuperClass = Class
  13.     Public
  14.       Procedure SuperMethod;
  15.   end;
  16.  
  17.   TCalcDamperOpeningSize = class
  18.       Procedure CalcThisAndThat(p1, p2, p3: Integer);
  19.   end;
  20.  
  21.   TCalcMotorData = class
  22.       function CalcSomethingElse(p1: integer; p2: Double): Double;
  23.   end;
  24.  
  25.   TChildClass1 = Class(TSuperClass)
  26.   end;
  27.  
  28.    TChildClass2 = Class(TSuperClass)
  29.    public
  30.          ThisAndThat: TThisAndThat;
  31.          SomeThingElse: TSomeThingElse;
  32.    end;
  33.  
  34. Var
  35.   c1:TChildClass1;
  36.   c2:TChildclass2;
  37.   CalcDamperOpeningSize: TCalcDamperOpeningSize;  
  38.   CalcMotorData: TCalcMotorData;
  39.  
  40. begin
  41.   c1:=TChildClass1.Create;
  42.   c1.SuperMethod;
  43.   c1.Free;
  44.  
  45.    CalcDamperOpeningSize := TCalcDamperOpeningSize.Create;
  46.    CalcMotorData := TCalcMotorData.Create;
  47.  
  48.    c2:=TChildClass1.Create;
  49.    c2.SuperMethod;
  50.  
  51.    C2.ThisAndThat := CalcDamperOpeningSize.CalcThisAndThat;
  52.    C2.SomeThingElse:= CalcMotorData.CalcSomeThingElse;
  53.    c2.ThisAndThat(i1, i2, i3);
  54.    c2.SomethingElse (i1, d1);
  55.  
  56.    c2.Free;
  57.  
  58.    CalcDamperOpeningSize.Free;
  59.    CalcMotorData.Free;
  60.  
  61. end.
  62.  
  63.  

y.ivanov

  • Sr. Member
  • ****
  • Posts: 306
Re: Representing Methods in different Classes
« Reply #19 on: October 22, 2021, 10:50:55 am »
As of given example, it looks like machine/parts class aggregation example given usually in UML tutorials. If this is the case, you should not derive parts (or machine with) from the machine class itself, but keep them in separate class hierarchy and add them into machine as references.

Same thing that SymbolicFrank advised.

MarkMLl

  • Hero Member
  • *****
  • Posts: 3526
Re: Representing Methods in different Classes
« Reply #20 on: October 22, 2021, 11:13:57 am »
Same thing that SymbolicFrank advised.

Much the same as I suggested but SymbolicFrank's way is superior since the items can be addressed by name so are extensible.

MarkMLl
MT+86 & Turbo Pascal v1 on CCP/M-86, multitasking with LAN & graphics in 128Kb.
Pet hate: people who boast about the size and sophistication of their computer.
GitHub repositories: https://github.com/MarkMLl?tab=repositories

Mr.Madguy

  • Hero Member
  • *****
  • Posts: 737
Re: Representing Methods in different Classes
« Reply #21 on: October 22, 2021, 11:31:06 am »
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.
Code: Pascal  [Select][+][-]
  1. TSuperClass = interface;
  2.  
  3. TSuperClassImplementation = class(TInterfacedObject, TSuperClass);
  4. TSubClassImplementation1 = class(TSuperClassImplementation)
  5.   //Implement your Method 1 here
  6. end;
  7. TSubClassImplementation2 = class(TSuperClassImplementation)
  8.   //Implement your Method 2 here
  9. end;
  10. //etc.
  11. var
  12.   MyObject:TSuperClass;
  13.  
  14. MyObject := TSubClassImplementation1.Create;
  15.  
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.
Code: Pascal  [Select][+][-]
  1. //First variant
  2. TAbstractMethodImplementation = class;
  3. //Second variant
  4. TMethod = procedure of object;
  5.  
  6. TMethodImplementation1 = class(TAbstractMethodImplementation);
  7. TMethodImplementation2 = class(TAbstractMethodImplementation);
  8. TMethodImplementation3 = class(TAbstractMethodImplementation);
  9.  
  10. TSuperClass = class
  11. protected
  12.   FMethodImplementation:TAbstractMethodImplementation;
  13.   //For second variant, use FMethod := FMethodImplementation.MyMethod
  14.   FMethod:TMethod;
  15. public
  16.   procedure MyMethod;
  17. end;
  18.  
  19. //Yeah, clunky stubs are needed
  20. procedure TSuperClass.MyMethod;
  21. begin
  22.   FMethodImplementation.MyMethod;
  23.   //Second variant
  24.   //Just call FMethod;
  25. end;
  26.  
  27. TSupClass1 = class(TSuperClass)
  28.   constructor Create;
  29. end;
  30.  
  31. constructor TSupClass1.Create;
  32. begin
  33.   FMethodImplementation := TMethodImplementation1.Create;
  34. end;
  35.  
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.
Code: Pascal  [Select][+][-]
  1. TInterfaceWithOtherClasses = class;
  2.  
  3. TAbstractMethodImplementation = class(TInterfaceWithOtherClasses:virtual);
  4.  
  5. TMethodImplementation1 = class(TAbstractMethodImplementation);
  6. TMethodImplementation2 = class(TAbstractMethodImplementation);
  7. TMethodImplementation3 = class(TAbstractMethodImplementation);
  8.  
  9. TSuperClass = class(TInterfaceWithOtherClasses:virtual);
  10.  
  11. //FULL POWER OF MULTIPLE INHERITANCE IN JUST ONE LINE OF CODE!!!
  12. TSubClass1 = class(TSuperClass, TMethodImplementation1:override);
  13.  
« Last Edit: October 22, 2021, 12:29:24 pm by Mr.Madguy »
24.11.2021 - DynamicData 4.0 runtime is overhauled to improve scalability.
My project still requires full Delphi 2009 support to be ported to Lazarus.
It's time to finally do it, because Delphi 2009 is 12 years old.

 

TinyPortal © 2005-2018