さて、最近の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なメソッドのみが
使用できます。
0 件のコメント:
コメントを投稿