さて、最近のDelphiでは、ネストした型宣言が可能で、クラス宣言の中にクラスの宣言ができます。
この機能を使って、クラスの使用者からpublishedなメソッドを隠すことを試してみました。
以下、ソースです。
先ず、 【関数名でメソッドが呼び出されるクラスのサンプル】
unit Unit2; interface type TMyCallCalc = class public function CallCalc(CalcName : string; a, b: double) : double; private type TMyCalc = class published function Add(a,b : double) : double; function Subtract(a,b : double) : double; end; end; implementation { TMyCalc } function TMyCallCalc.TMyCalc.Add(a, b: double): double; begin Result := a + b; end; function TMyCallCalc.TMyCalc.Subtract(a, b: double): double; begin Result := a - b; end; type TMyCalcFunc = function(a,b : double) : double of object; function TMyCallCalc.CallCalc(CalcName : string; a, b: double) : double; var MyCalc : TMyCalc; MyCalcFunc : TMyCalcFunc; MethodVar : TMethod; begin MyCalc := TMyCalc.Create; try MethodVar.Data := MyCalc; MethodVar.Code := MyCalc.MethodAddress(CalcName); if Assigned(MethodVar.Code) then begin MyCalcFunc := TMyCalcFunc(MethodVar); Result := MyCalcFunc(a,b); end; finally MyCalc.Free; end; end; end.
親クラスのprivateセクションにpublishedなメソッドを持つ子クラスを宣言しています。
これで、ユニットの使用者からは、子クラスのメソッドの宣言が見えなくなり、直接呼び出す
ことができなくなります。
ユニットの使用者には、publicセクションにメソッドを宣言することで、間接的に目的の
メソッドが呼び出せるようにします。
次に上記のクラスを使用するコード
unit Unit1; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls; type TForm1 = class(TForm) Button1: TButton; Button2: TButton; LabeledEdit1: TLabeledEdit; LabeledEdit2: TLabeledEdit; StaticText1: TStaticText; StaticText2: TStaticText; procedure OnCalcBtnClick(Sender: TObject); private { Private 宣言 } public { Public 宣言 } end; var Form1: TForm1; implementation {$R *.dfm} uses Unit2; procedure TForm1.OnCalcBtnClick(Sender: TObject); var CallCalc : TMyCallCalc; begin CallCalc := TMyCallCalc.Create; try StaticText2.Caption := FloatToStr(CallCalc.CallCalc( TButton(Sender).Caption, StrToFloat(LabeledEdit1.Text), StrToFloat(LabeledEdit2.Text))); finally CallCalc.Free; end; end; end.
ユニットを使用する側からは子クラスが見えませんので、親クラスのpublicなメソッドのみが
使用できます。