Унаследованная зависимость класса от переопределения класса
У меня есть эти 2 класса:
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
.
Ответы
Ответ 1
Ключевым моментом является выполнение проверки логического значения один раз в базовом классе. Итак, сделайте 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;
Ответ 2
Вам нужно поймать исключение 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;