有一个父类假设叫A,有几个从A继承的子类A1,A2,A3......
在主控程序中,我希望创建A1, A2, A3......
我想采用工厂模式能够方便些
但是我的疑惑是我怎样创建A1,A2,A3......
我看到一些书上的例子是这样的:
if ( sClassName='A1') then
A1.Create();
else if sClassName='A2' then
A2.Create();
......
我感觉这样仅仅是代码进行了封装,并没有进行抽象呀,有没有办法实现抽象呀?比如
函数(sClassName).Create 就是直接将字符串sClassName转换成类名
getClass可以将字符串转换成类,但是转换成的类还是需要进行类型转换的,现在我的想法就是希望工厂(主控程序)不必知道具体要创建什么类,只要在数据库或者配置文件中写好要创建多少类,系统就可以自动创建
在主控程序中,我希望创建A1, A2, A3......
我想采用工厂模式能够方便些
但是我的疑惑是我怎样创建A1,A2,A3......
我看到一些书上的例子是这样的:
if ( sClassName='A1') then
A1.Create();
else if sClassName='A2' then
A2.Create();
......
我感觉这样仅仅是代码进行了封装,并没有进行抽象呀,有没有办法实现抽象呀?比如
函数(sClassName).Create 就是直接将字符串sClassName转换成类名
getClass可以将字符串转换成类,但是转换成的类还是需要进行类型转换的,现在我的想法就是希望工厂(主控程序)不必知道具体要创建什么类,只要在数据库或者配置文件中写好要创建多少类,系统就可以自动创建
解决方案 »
- cxgrid 怎么 对一个字段进行控制
- 国庆中秋散分
- webbrowser打开页面后如何获取其中的文字
- 关于intraweb中iwdbgrid数据单击事件的问题?
- 急!,请高手帮忙
- 类型转换问题(二)?
- INI问题:如何删除里面的数据.高手问题,在线等待!。×××××
- ADOQUERY通过MYoledb联接MYSQL数据库,更新记录时出错!急......
- 求救,关于QuickRep.Preview 的简单问题,谢谢,急,急,急,马上给分
- 分布式系统中,怎样用delphi2007中dbx4控件组实现 巢状数据表 Master/Detail的应用系统
- 如何实现mpg4的文件合并?
- 模拟鼠标行为,但不是用程序控制鼠标,急急急!!!
delphi 不清楚
class Creator
{
public:
virtual Product* CreateProduct() = 0 ;
};template < class ConcreteProduct > // 就是你上面说的 A1, A2....
class ConcreteCreator: public Creator
{
public:
virtual Product* CreateProduct() { return new ConcreteProduct() ; }
};
子中,我们准备用专门创建的一个叫PanelMaker的类的CreatePanel方法来创建我们的
面板。TypeTPanelMaker = class (TObject)
public
function CreatePanel( aOwner : TWinControl;
Factory : TAbstractFactory ): TPanel;
end;implementationfunction TPanelMaker.CreatePanel(aOwner : TWinControl; Factory : TAbstractFactory): TPanel;
var
TempPanel : TPanel;
TempEdit1 : TEdit;
TempEdit2 : TEdit;
TempEdit3 : TEdit;
begin
TempPanel := Factory.MakePanel( aOwner );
TempEdit1 := Factory.MakeEdit( TempPanel, 'Test1', 10, 10 );
TempEdit2 := Factory.MakeEdit( TempPanel, 'Test2', TempEdit1.Top + TempEdit1.Height + 10,
TempEdit1.Left );
TempEdit3 := Factory.MakeEdit( TempPanel, 'Test3', TempEdit2.Top + TempEdit2.Height + 10,
TempEdit2.Left );
CreatePanel := TempPanel;
end;请注意,我们并没有直接用TPanel.Create来创建我们的面板,而是用了一个抽象工厂的
方法MakePanel来代替它,这样,如果我们要改动的时候,将变得更加容易。抽象工厂的具体定义如下:typeTAbstractFactory = class (TObject)
protected
FPanel : TPanel;
public
function MakeEdit( aOwner : TWinControl;vText : string;vTop : Integer;vLeft : Integer ): TEdit; virtual;
function MakePanel( aOwner : TWinControl ) : TPanel; virtual;
end;implementationfunction TAbstractFactory.MakeEdit( aOwner : TWinControl;vText : string;vTop : Integer;vLeft : Integer ): TEdit;
var
TempEdit : TEdit;
begin
TempEdit := TEdit.Create( aOwner );
TempEdit.Parent := aOwner;
TempEdit.Text := vText;
TempEdit.Top := vTop;
TempEdit.Left := vLeft;
MakeEdit := TempEdit;
end;function TAbstractFactory.MakePanel( aOwner : TWinControl ) : TPanel;
var
TempPanel : TPanel;
begin
TempPanel := TPanel.Create( aOwner );
TempPanel.Parent := aOwner;
MakePanel := TempPanel;
end;这个定义是用来创建标准编辑框和标准面板的,但是,如果我们想要创建一个特殊类型
的编辑框,比如说,我们希望那个编辑框只允许大写字母。TypeTUppercaseEdit = class (TEdit)
protected
FOnChange : TNotifyEvent;
procedure Change; override;
function GetUppercase : string;
procedure SetUppercase( Value : string );
public
property Text : string read GetUppercase write SetUppercase;
end;现在你可以创建一个用这个编辑框来代替标准编辑框的抽象工厂类的子类。function TUppercaseFactory.MakeEdit( aOwner : TWinControl;vText : string;vTop : Integer;vLeft : Integer ): TEdit;
var
TempEdit : TUppercaseEdit;
begin
TempEdit := TUppercaseEdit.Create( aOwner );
TempEdit.Parent := aOwner;
TempEdit.Text := vText;
TempEdit.Top := vTop;
TempEdit.Left := vLeft;
MakeEdit := TempEdit;
end;就像这样,你并不需要对PanelMaker.CreatePanel方法有任何改动。
我在A中定义了一些虚方法,比如f1,f2,在每个子类中overload了f1,f2,写了自己的实现,factory中定义了一个actionForm,类型是父类型
问题是但是如果直接使用actionForm.f1调用的是A中的f1方法,我希望能够执行子类型的方法
面向對象中的多態可以保證你要的如
var
a: TA;
begin
a := TChildA.Create;
a.f1; 這樣調用的 TChildA的 f1 方法>>在每个子类中overload了
應用用 override
TabstractA=class(Tobject)
......
TA1=class(TabstractA)
......
TA2=class(TabstractA)
......
TA3=class(TabstractA)
......
实现时应为
var Taa;TabstractA
begin
Taa:=TabstractA(TA1.create);
end;
注意的是抽象类接口和派生类接口的定义是一样的