我有这两个班级:
type
TMyBaseClass = class
protected
FAllowDoSomething: Boolean; // initialized to False
procedure DoSomething; virtual;
end;
TMyChildClass = class(TMyBaseClass)
protected
procedure DoSomething; override;
end;
implementation
procedure TMyBaseClass.DoSomething;
begin
if not FAllowDoSomething then Exit; // Abort;
ShowMessage('TMyBaseClass: FAllowDoSomething is False. You wont see me!');
end;
procedure TMyChildClass.DoSomething;
begin
inherited; // Must inherit
// if not FAllowDoSomething then Exit; { I don't want to check here again }
ShowMessage('TMyChildClass: FAllowDoSomething is False but still I can see this message!');
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
with TMyBaseClass.Create do try
DoSomething;
finally
Free;
end;
// if I use Abort in TMyBaseClass, the code will not get here
with TMyChildClass.Create do try
DoSomething;
finally
Free;
end;
end;
在TMyChildClass.DoSomething
我必须inherited
TMyBaseClass.DoSomething
,但我希望它尊重if not FAllowDoSomething then <don't do anything>
。
我尝试在Abort
中使用TMyBaseClass
,但我发现这不是一个好主意,会打破调用方法(TForm1.Button1Click
);
如果不在if not FAllowDoSomething then Exit
中再次编写TMyChildClass
,这样做的正确方法是什么。
答案 0 :(得分:11)
关键是在基类中对布尔值执行一次检查。所以,让DoSomething非虚拟化并在你的基类中实现它,如下所示:
procedure TMyBaseClass.DoSomething;
begin
if FAllowDoSomething then
DoSomethingImplementation;
end;
其中DoSomethingImplementation是您在派生类中重写的虚方法。
基类看起来像这样:
type
TMyBaseClass = class
private
FAllowDoSomething: Boolean;
protected
procedure DoSomethingImplementation; virtual;
public
procedure DoSomething;
end;
您的派生类看起来像这样:
type
TMyDerivedClass = class(TMyBaseClass)
protected
procedure DoSomethingImplementation; override;
end;
您的被覆盖方法如下所示:
procedure TMyDerivedClass.DoSomethingImplementation;
begin
inherited;
ShowMessage(...);
end;
答案 1 :(得分:0)
您需要捕获Abort
例外。
procedure TMyBaseClass.DoSomething;
begin
if not FAllowDoSomething then Abort;
ShowMessage('TMyBaseClass: FAllowDoSomething is False. You wont see me!');
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
with TMyBaseClass.Create do
try
try
DoSomething;
finally
Free;
end;
except
on EAbort do ;
end;
// the code will get here
with TMyChildClass.Create do
try
try
DoSomething;
finally
Free;
end;
except
on EAbort do ;
end;
end;