如何内一类保持其独特的方法封装不同类别? (在Delphi多重继承?)
-
23-09-2019 - |
题
我目前重写自由教育数字电路模拟器inertiality添加到它的功能。我的问题是如何调度事件,以便原班增加预阐述他们。我有这样的事情:
TC1 = class
ID: integer;
Connections : array [integer] of Pin;
function Func1; virtual;
function FuncN;
end;
TC2-1 = class (TC1)
function Func1; override;
function My1Func();
end;
TC2-n = class (TC1)
function Func1; override;
function MyNFunc();
end;
TContainer = class
C1 : TC1;
function ContFunc;
end;
function Container.ContFunc;
begin
c1.Func1;
end;
现在这意味着ContFunc呼叫C2.Func1如祝,专业超过300个组件继承形式TC1的行为。
但现在我必须添加一些特殊的操作(等于所有组件后代 从TC1每FUNC1时间被调用,期间操作艇员选拔如果我有 调用TC2-n.Func1与否(改变祖先TC1的某些属性后。 有没有办法做到这一点干净,不改变TC1的后代? 我可以使用一个辅助类像这样(不推荐):
TH = class helper of TC1
function Func1 virtual; override;
end;
function TH.Func1;
begin
if x then TC2.Func1 else SaveActionData;
end
如果我添加TH,当TContainer通话FUNC1,谁在叫? 它叫TC2.Func1而不是TH.Func1我希望? 有没有一种方法来覆盖descenants方法FUNC1 而无需编写一个辅助类的任何单独一个(他们将尽一切 相同的操作,意思正好等于代码)? 所以能够从TH调用300个后裔功能FUNC1 TC2-N
在换句话说,我试图找到一种方式来获得这样的Tcontainer呼叫c1.Func1呼叫;
NewFunc1(等于所有TC1后代)谁呼叫TC2.Func1(为TC1的任何后裔不同)。
任何人都可以提出一个方法来做到这一点?
解决方案
您有一些任务,每当有人呼叫Func1
,不管是什么后裔都选择在他们覆盖的方法做的,执行的需要。这是为在模板方法的工作强>图案。
提供基类的一个公共非虚拟方法Func1
执行的操作则需要,然后调用一个受保护的虚拟方法。后代可以重写虚拟的方法,但使用类人只能拨打公非虚拟方法。
type
TC1 = class
protected
function InternalFunc1: Integer; virtual; // abstract?
public
function Func1: Integer;
end;
function TC1.Func1;
begin
if x then
Result := InternalFunc1
else
Result := SaveActionData;
end;
现在的后代可以覆盖InternalFunc1
,基类将肯定使被称为只有在适当的时候。
type
TC2 = class(TC1)
protected
function InternalFunc1: Integer; override;
end;
您将需要在所有的300子孙类重命名当前Func1
功能。 IDE的重构工具或许能够提供帮助的。
其他提示
类助手是用于修改你不能在源获得的类是有用的。如果你是TC1类的作者,你将能够使通过引入TC1一类的辅助必要的更改,那么为什么不直接修改TC1.Func1,然后你做了什么?应工作。
您可以做以下的装饰模式来描述,当你的程序在模拟模式下运行出现需要特殊任务的包装类。它可以容纳您的数字组件的一个实例,并调用执行自己的任务后,该组件的方法。
type
TAnalogueDecorator = class(TC1)
private
FComponent: TC1;
public
constructor Create(Wrapped: TC1);
destructor Destroy; override;
function Func1: Integer; override;
end;
constructor TAnalogueDecorator.Create(Wrapped: TC1);
begin
inherited Create;
FComponent := Wrapped;
end;
destructor TAnalogueDecorator.Destroy;
begin
FComponent.Free;
inherited;
end;
function TAnalogueDecorator.Func1: Integer;
begin
SaveActionData;
Result := FComponent.Func1;
end;
也许你注意到没有必要事先检查你的x
条件。相反,在每次调用任何方法时,检查它的,你可以模拟一个包裹数字组件前一次检查。现在,所有您最初叫Func1
直接在数码类的地方会首先绕道到模拟类的方法。