2012年12月13日木曜日

publishedなメソッドを隠す(ネストした型宣言使用編)

前回の続きです。

さて、最近のDelphiでは、ネストした型宣言が可能で、クラス宣言の中にクラスの宣言ができます。

この機能を使って、クラスの使用者からpublishedなメソッドを隠すことを試してみました。

以下、ソースです。

先ず、 【関数名でメソッドが呼び出されるクラスのサンプル】

  1. unit Unit2;  
  2.   
  3. interface  
  4.   
  5.   type TMyCallCalc = class  
  6.     public  
  7.       function CallCalc(CalcName : string; a, b: double) : double;  
  8.     private  
  9.       type TMyCalc = class  
  10.         published  
  11.           function Add(a,b : double) : double;  
  12.           function Subtract(a,b : double) : double;  
  13.       end;  
  14.   
  15.   end;  
  16.   
  17.   
  18. implementation  
  19. { TMyCalc }  
  20.   
  21. function TMyCallCalc.TMyCalc.Add(a, b: double): double;  
  22. begin  
  23.   Result := a + b;  
  24. end;  
  25.   
  26. function TMyCallCalc.TMyCalc.Subtract(a, b: double): double;  
  27. begin  
  28.   Result := a - b;  
  29. end;  
  30.   
  31.   
  32. type TMyCalcFunc = function(a,b : double) : double of object;  
  33.   
  34. function TMyCallCalc.CallCalc(CalcName : string; a, b: double) : double;  
  35. var  
  36.   MyCalc     : TMyCalc;  
  37.   MyCalcFunc : TMyCalcFunc;  
  38.   MethodVar : TMethod;  
  39. begin  
  40.   
  41.   MyCalc := TMyCalc.Create;  
  42.   try  
  43.     MethodVar.Data := MyCalc;  
  44.     MethodVar.Code := MyCalc.MethodAddress(CalcName);  
  45.   
  46.   
  47.     if Assigned(MethodVar.Code) then  
  48.     begin  
  49.       MyCalcFunc := TMyCalcFunc(MethodVar);  
  50.       Result := MyCalcFunc(a,b);  
  51.     end;  
  52.   finally  
  53.     MyCalc.Free;  
  54.   end;  
  55.   
  56. end;  
  57.   
  58. end.  

親クラスのprivateセクションにpublishedなメソッドを持つ子クラスを宣言しています。
これで、ユニットの使用者からは、子クラスのメソッドの宣言が見えなくなり、直接呼び出す
ことができなくなります。
ユニットの使用者には、publicセクションにメソッドを宣言することで、間接的に目的の
メソッドが呼び出せるようにします。

次に上記のクラスを使用するコード

  1. unit Unit1;  
  2.   
  3. interface  
  4.   
  5. uses  
  6.   Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,  
  7.   Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls;  
  8.   
  9. type  
  10.   TForm1 = class(TForm)  
  11.     Button1: TButton;  
  12.     Button2: TButton;  
  13.     LabeledEdit1: TLabeledEdit;  
  14.     LabeledEdit2: TLabeledEdit;  
  15.     StaticText1: TStaticText;  
  16.     StaticText2: TStaticText;  
  17.     procedure OnCalcBtnClick(Sender: TObject);  
  18.   private  
  19.     { Private 宣言 }  
  20.   public  
  21.     { Public 宣言 }  
  22.   end;  
  23.   
  24. var  
  25.   Form1: TForm1;  
  26.   
  27. implementation  
  28.   
  29. {$R *.dfm}  
  30.   
  31. uses Unit2;  
  32.   
  33. procedure TForm1.OnCalcBtnClick(Sender: TObject);  
  34. var  
  35.   CallCalc : TMyCallCalc;  
  36. begin  
  37.   CallCalc := TMyCallCalc.Create;  
  38.   try  
  39.     StaticText2.Caption := FloatToStr(CallCalc.CallCalc(  
  40.                                     TButton(Sender).Caption,  
  41.                                     StrToFloat(LabeledEdit1.Text),  
  42.                                     StrToFloat(LabeledEdit2.Text)));  
  43.   finally  
  44.     CallCalc.Free;  
  45.   end;  
  46.   
  47. end;  
  48.   
  49. end.  

ユニットを使用する側からは子クラスが見えませんので、親クラスのpublicなメソッドのみが
使用できます。



0 件のコメント: