有时候我们可能在程序中需要动态去生成一些对象,但我们又不想写大量的case分支语句来实现,而是建一张表,根据类的名称或其他一些索引来生成类的实例——对象。如果你有这方面的需要,本文将会帮助你实现这一目的。
在写正文之前首先要引进一个概念,类的变量(自己起的准确不准确无所谓,只大家明白就行啦)。这个类的变量并非我们平时看到的这样的定义如:Edit1:TEdit。这样的定义只是定义了一个对象。如果想定义类的变量,我们需要这样定义,首先要定义一个类型类的类 Type TEditClass=class of Tedit;这样的话TEditClass就是一个类的类型。我们就可以通过:Var EditClass:TEditClaa;来定义类的变量了。如果我们想来生成一个TEdit的实例,就可以通过下面这段程序来实现:
type TEditClass=class of TEdit;
procedure TForm1.Button1Click(Sender: TObject);
var EditClass:TEditClass;
Edit1:TEdit;
begin
EditClass:=TEdit;
Edit1:=EditClass.Create(self);
Edit1.Parent :=self;
end;
这段代码也许没什么意义,但如果有大量的对象的时候,这样做的用处就显出来了。那就是可以根据类名或其它的东西来生成类的实例。而不是用大量的CASE语段来判断该生成什么对象。需要注意的是,我上面定了的类之类是TEditClass,如果换成TEDIT的父类也是适用的。 如果把 Type TEditClass = class of TEdit 换成 TWInControlClass = class of TWinControl,程序照样可以正确运行。
要想实现标题所提到的想法,我们可以这样实现,构建一张表,其中至少有两个字段,一个索引(比如字符串或整数等等),另一个就是类的变量,当然也可以加其他一些辅助的信息。这要视具体的情况而定。在需要生成对象的时候,我们可以先查找索引,如字符串或整数,再根据索引指向的类的变量来生成实例。
使用这种方法一定要注意:定义类的类的时候,这个类要是你需要生成类的父类,并且它们的构造函数的参数完全一样。
这种方案可以做为使用工厂模式的一种具体实现方案。工厂类可以不知道自己有多少产品类,产品类自动用工厂类的增加方法来把自己添加到工厂类的产品列表中去。到产出产品对象的时候,工厂类自动根据产品名称来生成产品类。这样可以保证工厂类的绝对稳定性,即新增加产品的时候,工厂类不用做任何改动就可以运行。