非常に役立つ可能性があるが、保護されたスコープのために利用できないメソッドを持つクラスがあるとします。
unit Sealed;
interface
type
TGeneral = class(TObject)
{ this method is useful, but not available }
protected procedure Useful; virtual;
end;
TSpecific1 = class(TGeneral)
{ some descendants override `Useful` method }
protected procedure Useful; override;
end;
TSpecific2 = class(TGeneral)
{ and some dont, but inherit `Useful`ness from the parent }
end;
私は、そのような方法に手を差し伸べる 2 つの昔ながらの方法を知っています。どちらも、継承と型キャストが関係しています。どちらのアプローチも、基本的なケース #1 と高度なポリモーフィック ケース #2 で同じように機能するはずです。
program CallingSite;
uses Sealed;
function GetInstance: TGeneral;
begin
{ !PSEUDO! makes compiler happy about the rest of code }
// depending on use case supposed to return an instance of `TGeneral`
// or any of its descendants - `TSpecific1`, `TSpecific2`
end;
type
{ this makes a current module a "friend" for `TGeneral` }
TFriend = class(TGeneral)
end;
procedure Case1;
var
{ holds an instance of `TGeneral` }
General: TGeneral;
begin
General := GetInstance;
{ protected method is available for "friend" via static cast }
TFriend(General).Useful; // compiles!
end;
type
TIntroducer = class(TGeneral)
{ this "reintroduces" `Useful` method to public scope }
public procedure Useful; override;
// this approach ought to work even with strict protected methods
// !!! but I THINK it is UNSAFE to use on virtual and/or dynamic methods
end;
procedure TIntroducer.Useful;
begin
{ and calls `Useful` via wrapper }
inherited;
end;
procedure Case2;
var
{ polymorphic instance of any `TGeneral`'s descendant }
Specific: TGeneral;
begin
Specific := GetInstance;
{ protected method is callable via public wrapper, static cast again }
TIntroducer(Specific).Useful; // compiles!
end;
知りたい:
- クラスヘルパーの力を適用して同じ結果を得るにはどうすればよいですか?
- クラスヘルパーでもプライベートメソッドを呼び出すことは可能ですか?
- 内部表現ではなく、どのクラスヘルパーがクラススコープを拡張するという事実により、ケース#1とケース#2の間に違いはありますか?
- 再帰の危険を冒さずにクラスヘルパーで再導入されたメソッドから元のメソッドを呼び出す方法は?
また、不安全に関する発言についてはコメントをお願いしTIntroducer
ます。