Chr*_*ler 6 delphi generics inheritance software-design downcast
我想对以下问题提出一些建议:假设你想为VCL控件编写适配器.所有适配器应具有相同的基类,但在包装特殊控件方面有所不同(例如,从TEdit获取值与从TSpinEdit获取值不同).所以第一个想法就是创建一个类层次结构
TAdapter = class
end;
TEditAdapter = class (TAdapter)
end;
TSpinEditAdapter = class (TAdapter)
end;
Run Code Online (Sandbox Code Playgroud)
现在我想引入一个字段来保存对vcl控件的引用.在我的特殊适配器中,我想 - 当然 - 使用具体的子类.但是Base类还应该包含一个引用(例如,如果我想使用适配器使控件可见).
可能性1(物业存取中的向下):
TAdapter = class
protected
FCtrl : TControl;
end;
TEditAdapter = class (TAdapter)
public
property Control : TEdit read GetControl write Setcontrol;
end;
{...}
function TEditAdapter.GetControl : TEdit;
begin
Result := FCtrl as TEdit;
end;
Run Code Online (Sandbox Code Playgroud)
因此,如果我实现一个特定的方法,我使用属性Control,如果我在基类中执行某些操作,则使用protected字段.
可能性2(使用通用基类):
TAdapter = class
end;
TAdapter <T : TControl> = class (TAdapter)
protected
FCtrl : T;
end;
TEditAdapter = class (TAdapter <TEdit>)
end;
Run Code Online (Sandbox Code Playgroud)
您更喜欢哪种解决方案?还是有第三种解决方案,哪种更好?
亲切的问候,
基督教
你不能使用泛型来解决这个问题,因为你会遇到以下两种情况之一:
Text例如属性)是在祖先类中定义的。在这种情况下,您不需要泛型,因为您可以为祖先使用一个适配器并解决所有后代的问题。Text属性的适配器TMyClass。我们假设TMyClass是介绍该房产的人Text。为了访问它,您需要将泛型类型声明为TGeneric<T:TMyClass>,而这实际上并不是泛型。在我看来,最好的选择是为每个类编写特定的适配器,就像您的第一个选择一样。您也许可以使用 RTTI 技巧来使您的第一个选项更容易实现,但我不确定这是否值得。