Recent

Author Topic: Change type of class field  (Read 1739 times)

SymbolicFrank

  • Hero Member
  • *****
  • Posts: 1313
Change type of class field
« on: January 31, 2022, 12:40:13 pm »
I would like to do something like this:

Code: Pascal  [Select][+][-]
  1.   Item1 = class
  2.   end;
  3.  
  4.   Item2 = class(Item1)
  5.   end;
  6.  
  7.   Class1 = class
  8.   protected
  9.     MyItem: Item1;
  10.   end;
  11.  
  12.   Class2 = class(Class1)
  13.   protected
  14.     MyItem: Item2;    // <-- This
  15.   end;

There is a big class hierarchy of which I want to change a single thing, by changing a single method of an encapsulated field. But you cannot "upgrade" fields this way, AFAIK. The idea is that you create an instance of Item2 and assign that to MyItem, not the other way around. So, I don't think that, if it could be done, the right constructor is called.


Zvoni

  • Hero Member
  • *****
  • Posts: 2330
Re: Change type of class field
« Reply #1 on: January 31, 2022, 01:35:15 pm »
?? This?
Code: Pascal  [Select][+][-]
  1. program Project1;
  2. Uses Classes;
  3. Type
  4.  
  5.   { Item1 }
  6.  
  7.   Item1 = class
  8.   Public
  9.     Constructor Create;
  10.   end;
  11.  
  12.   { Item2 }
  13.  
  14.   Item2 = class(Item1)
  15.     Public
  16.       Constructor Create;
  17.   end;
  18.  
  19.   { Class1 }
  20.  
  21.   Class1 = class
  22.   Strict Private
  23.     FMyItem:Item1;
  24.   protected
  25.     Property MyItem: Item1 Read FMyItem Write FMyItem;
  26.   end;
  27.  
  28.   { Class2 }
  29.  
  30.   Class2 = class(Class1)
  31.   Strict Private
  32.     FMyItem:Item2;
  33.   protected
  34.     Property MyItem: Item2 read FMyItem Write FMyItem;
  35.   end;
  36.  
  37. { Item1 }
  38.  
  39. constructor Item1.Create;
  40. begin
  41.   Writeln('Item1 created');
  42. end;
  43.  
  44. { Item2 }
  45.  
  46. constructor Item2.Create;
  47. begin
  48.   Writeln('Item2 created');
  49. end;
  50.  
  51. Var
  52.   C1:Class1;
  53.   C2:Class2;
  54.  
  55. begin
  56.   C1:=Class1.Create;
  57.   C2:=Class2.Create;
  58.   C1.MyItem:=Item1.Create;
  59.   C2.MyItem:=Item2.Create;
  60.   C1.MyItem.Free;
  61.   C2.MyItem.Free;
  62.   C1.Free;
  63.   C2.Free;
  64. end.
  65.  

Prints for Lines 58/59
Item1 created
Item2 created
« Last Edit: January 31, 2022, 01:36:59 pm by Zvoni »
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

engkin

  • Hero Member
  • *****
  • Posts: 3112
Re: Change type of class field
« Reply #2 on: January 31, 2022, 02:02:14 pm »
There is a big class hierarchy of which I want to change a single thing, by changing a single method of an encapsulated field.

Can you show a more precise example?

SymbolicFrank

  • Hero Member
  • *****
  • Posts: 1313
Re: Change type of class field
« Reply #3 on: February 01, 2022, 09:56:27 am »
Well, I keep changing unit dbf and some of the included ones. Like, I needed to overwrite AutoInc fields and change the field with the next value. All fields of TDbf are private, unfortunately. One of them,

Code: Pascal  [Select][+][-]
  1. FDbfFile: TDbfFile;

inherits from TPagedFile, which does those things. Like, it has this function:

Code: Pascal  [Select][+][-]
  1. procedure ApplyAutoIncToBuffer(DestBuf: TRecordBuffer);

which I need to change, which is unfortunately not virtual.

And I'm part of a team, it would be nice if my teammates had the same version, which is diverging from trunk. The last bugfix submitted is not merged with trunk yet, so I have to maintain my own version.

But I would prefer to keep the changes as small as possible, if possible by making new classes that inherit from and replace those. Not by duplicating 9 units with thousands of lines of code.

@Zvoni: more like this:

Code: Pascal  [Select][+][-]
  1. begin
  2.   C1:=Class1.Create;
  3.   C2:=Class2.Create;
  4.   C1.MyItem:=Item1.Create;
  5.   C2.MyItem:=Item1.Create; // <-- This is done by an existing class, that knows nothing about Class2 or Item2.
  6.   C1.MyItem.Free;
  7.   C2.MyItem.Free;
  8.   C1.Free;
  9.   C2.Free;
  10. end.

Zvoni

  • Hero Member
  • *****
  • Posts: 2330
Re: Change type of class field
« Reply #4 on: February 01, 2022, 10:03:21 am »
hmm....looks more like an Interface

EDIT: have you thought about "reintroduce"?
https://wiki.freepascal.org/Reintroduce
« Last Edit: February 01, 2022, 10:19:42 am by Zvoni »
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

SymbolicFrank

  • Hero Member
  • *****
  • Posts: 1313
Re: Change type of class field
« Reply #5 on: February 01, 2022, 10:28:45 am »
hmm....looks more like an Interface

EDIT: have you thought about "reintroduce"?
https://wiki.freepascal.org/Reintroduce

Exactly. But for fields.

Zvoni

  • Hero Member
  • *****
  • Posts: 2330
Re: Change type of class field
« Reply #6 on: February 01, 2022, 10:40:36 am »
Maybe this: https://www.freepascal.org/docs-html/ref/refsu39.html
Rewrite the Field to a Property?
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad

SymbolicFrank

  • Hero Member
  • *****
  • Posts: 1313
Re: Change type of class field
« Reply #7 on: February 01, 2022, 10:46:51 am »
I already changed things so it works, but that requires ~ 10 small changes in two files. Ah, well, I'll make a list of diffs to incorporate.

I wanted to put FPC / Laz in our own Git repository as well, but it was deemed a tool and too big.

 

TinyPortal © 2005-2018