Recent

Author Topic: [Solved] Need help with encapsulation  (Read 1332 times)

nikel

  • Full Member
  • ***
  • Posts: 186
[Solved] Need help with encapsulation
« on: December 14, 2018, 12:24:34 pm »
Hi, I'm trying to set variable for a modal form. Here's my code:

Form1:

Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   ... countdown_dialog;
  9. ...
  10. procedure TForm1.WarnHandler;
  11. begin
  12.   if (WarnBeforeAction=True) then
  13.   begin
  14.     countdown_dialog.SetText('Test'); // Here I can't access the function
  15.     if (CountDownDialog_Frm.ShowModal=mrYes) then
  16.     begin
  17.       ApplyCommand;
  18.     end
  19.     else
  20. ...
  21.  

Code: Pascal  [Select][+][-]
  1. unit countdown_dialog;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   ...
  9.  
  10. type
  11.  
  12.   { TCountDownDialog_Frm }
  13.  
  14.   TCountDownDialog_Frm = class(TForm)
  15.     ...
  16.   private
  17.     function GetText: String;
  18.     procedure SetText(const Value: Integer);
  19. ...
  20. var
  21.   Str: String;
  22. ...
  23. function TCountDownDialog_Frm.GetText: String;
  24. begin
  25.   Result:=Str;
  26. end;
  27.  
  28. procedure TCountDownDialog_Frm.SetText(const Value: Integer);
  29. begin
  30.   Str:=Value;
  31. end;
  32.  

I'm not good at OOP but want to fix this. How can I access the second form's function?
« Last Edit: December 14, 2018, 01:30:00 pm by nikel »

Handoko

  • Hero Member
  • *****
  • Posts: 5131
  • My goal: build my own game engine using Lazarus
Re: Need help with encapsulation
« Reply #1 on: December 14, 2018, 12:52:53 pm »
Maybe:

Code: Pascal  [Select][+][-]
  1. unit Unit1;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   ... countdown_dialog;
  9. ...
  10. procedure TForm1.WarnHandler;
  11. begin
  12.   if (WarnBeforeAction=True) then
  13.   begin
  14.     countdown_dialog.Description := 'Test';
  15.     if (CountDownDialog_Frm.ShowModal=mrYes) then

See line #14 on the code above. To be able to do this you need to create a property in public/published visibility on the code below line #21.

Code: Pascal  [Select][+][-]
  1. unit countdown_dialog;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. interface
  6.  
  7. uses
  8.   ...
  9.  
  10. type
  11.  
  12.   { TCountDownDialog_Frm }
  13.  
  14.   TCountDownDialog_Frm = class(TForm)
  15.     ...
  16.   private
  17.     FDescription: string;
  18.     function GetText: string;
  19.     procedure SetText(const Value: string);
  20.   public
  21.     property Description: string read GetText write SetText;
  22. ...
  23. function TCountDownDialog_Frm.GetText: string;
  24. begin
  25.   Result := FDescription;
  26. end;
  27.  
  28. procedure TCountDownDialog_Frm.SetText(const Value: string);
  29. begin
  30.   FDescription := Value;
  31. end;
« Last Edit: December 14, 2018, 12:59:13 pm by Handoko »

wp

  • Hero Member
  • *****
  • Posts: 11857
Re: Need help with encapsulation
« Reply #2 on: December 14, 2018, 12:54:12 pm »
You want to call GetText of TCountdownDialog_Frm? You cannot because you declared it as "private". "Private" means: Only the class to which this method belongs can call it (and all other classes which are in the same unit - but this is not so good because it breaks encapsulation). But you can move it to the public section, or, better since you also have a SetText, you can declare a public property Text with GetText as "getter function" and SetText as "setter function:
Code: Pascal  [Select][+][-]
  1. type
  2.   TCountdown_Frm = class(TForm)
  3.     ...
  4.   private
  5.     function GetText: String;
  6.     procedure SetText(const Value: String);   // you have "Integer" here, I suppose you mean "String"
  7.     ...
  8.   public
  9.     property Text: String read GetText write SetText;
  10.   end;

Remark: the variable Str which is accessed by GetText/SetText is declared outside the class as a global variable. This is against OOP principles because when you instantiate a second form of TCountDown_Frm both forms are fighting for the same data variable, probably not what you want. If you move Str into the scope of TCountDown_Frm you can even drop the getter and setter functions:
Code: Pascal  [Select][+][-]
  1. type
  2.   TCountDown_Frm = class(TForm)
  3.   private
  4.     Str: String;
  5.     ...
  6.   public
  7.     property Text: String read Str write Str;
  8.   end;
   
[EDIT] Handoko was faster...

nikel

  • Full Member
  • ***
  • Posts: 186
Re: Need help with encapsulation
« Reply #3 on: December 14, 2018, 01:29:39 pm »
Sorry for my dirty code. I knew functions should be declared in public section. I was doing trial and error. What I'd been doing wrong was that I didn't use:

Code: Pascal  [Select][+][-]
  1. countdown_dialog.CountDownDialog_Frm.Description:='Test';

Thanks for the replies.

 

TinyPortal © 2005-2018