在delphi中如何动态建立类的实例

简介: 本文为原创,如需转载,请注明作者和出处,谢谢!     在面向对象语言中,用两种方法建立类的实例:静态建立和动态建立。静态建立就是在程序中显式地建立类的实例,如c1 = TClass1.Create()。
本文为原创,如需转载,请注明作者和出处,谢谢!


    在面向对象语言中,用两种方法建立类的实例:静态建立和动态建立。静态建立就是在程序中显式地建立类的实例,如c1 = TClass1.Create()。而动态建立是在只知道类名的前题下建立类的实例。动态建立在实现上要比静态建立更灵活,因为动态建立无需引用被建立 类,并且更容易实现如多态等面向对象特性。

一、    动态建立类的实例
在delphi中动态建立类的实例可分为4步。
1. 声明一个从TPersistent继承的类。因为在注册类时要求必须从TPersistent继承。
2. 注册类。可以使用RegisterClass等过程进行注册。
3. 验证类是否被注册(可选)。如果确定要建立的类已经注册了,可以省略此步。
4. 得到并建立类。可使用FindClass(classname)得到要建立的类,然后使用Create方法建立类的实例。
下面给出一个动态建立类实例的简单实现。
第一步的代码
TClass1 = class(TPersistent)
public
  function GetValue(): String;
end;

function TClass1.GetValue(): string;
begin
  result := 'hello world';
end;
第二步的代码
Initialization //可将这两行放在end.的前面
  RegisterClass(TClass1);
第三步和第四步的代码
procedure TForm1.Button1Click(Sender: TObject);
var
  class1: TClass1;
begin
  if GetClass('TClass1')<>nil then
  begin
    class1 := FindClass('TClass1').Create as TClass1;
    showmessage(class1.GetValue);
  end;
end;

在delphi 中不仅可以根据类名动态建立类的实例,而且在注册时可以给类起一个别名,在建立类的实例时即可以使用类名,也可以使用别名。如上述代码中 RegisterClass(TClass1);可改为RegisterClassAlias(TClass1, ‘class1’);。而FindClass(‘TClass1’)也可改为FindClass(‘class1’)。另外,如果注册的类比较多,也可使 用RegisterClasses一次注册多个类。RegisterClasses的定义如下。
procedure RegisterClasses(AClasses: array of TPersistentClass);
首先声明一个TpersistentClass类型的数组,然后将要注册的类按顺序赋到这个数组中,最后调用RegisterClasses即可。

二、通过动态建立实现多态
多 态在程序设计中是非常重要的概念之一。它主要是通过继承来实现的。简单地说,就是n个类从一个类继承或实现一个接口,这n个类继承父类的所有 virtual方法或实现父接口的所有方法,并做出不同的实现。这n个类的实现都不一样,而它们的调用确是一样的,即对于调用来说是透明的。
如果使用静态建立类实例的方法实现多态,当类很多时需要进行大量的判断。而使用动态建立类实例的方法只要将子类的类名或别名当做参数传入即可。下面举一个例子如何在delphi中利用动态建立类实例的方法实现多态。
  //定义父类
TClassParent = class(TPersistent)
  public
//这是一个抽象虚函数,相当于c++的纯虚函数
function Greet(name: string): string; virtual; abstract; 
end;
//定义两个子类
  TEnglish = class(TClassParent)
    function Greet(name: string): string; override;
  end;
  TChinese = class(TClassParent)
    function Greet(name: string): string; override;
  end;

  //实现两个子类的Greet函数
{ TClassEnglish }
function TEnglish.Greet(name: string): string;
begin
  result := 'hello ' + name;  //返回英文的问候
end;
{ TClassChinese }
function TChinese.Greet(name: string): string;
begin
  result := '您好 ' + name;  //返回中文的问候
end;

//注册两个子类
initialization
  RegisterClassAlias(TEnglish, 'eng');
  RegisterClassAlias(TChinese, 'chn');

//根据用户的选择建立类的实例
procedure TForm1.Button2Click(Sender: TObject);
var
  parent: TClassParent;
begin   
  if GetClass(combobox1.Items[combobox1.itemindex])<>nil then
  begin
//此处FindClass的参数可以是类名,也可以是别名
//本例中将类名放入了combobox中
    parent :=  FindClass(combobox1.Items[combobox1.itemindex]).Create as TClassParent;
    showmessage(parent.Greet('bill gates'));
  end;
end;
 
目录
相关文章
|
6月前
|
缓存 Java 数据库连接
扩展类的附加特性
扩展类的附加特性
49 0
|
缓存 IDE API
C#反射与特性(五):主类型成员操作
C#反射与特性(五):主类型成员操作
429 0
C#反射与特性(五):主类型成员操作
|
安全 C++ Windows
C++调用外部应用程序的方法的整理总结(常用)
一、三个SDK函数:  WinExec,ShellExecute ,CreateProcess可以实现调用其他程序的要求,其中以WinExec最为简单,ShellExecute比WinExec灵活一些,CreateProcess最为复杂。
3086 0
|
存储 Go
第三十章 使用系统监视器 - 编写用户定义的应用程序监视器类
第三十章 使用系统监视器 - 编写用户定义的应用程序监视器类
123 0
|
缓存
读源码长知识 | 动态扩展类并绑定生命周期的新方式
在阅读viewModelScope源码时,发现了一种新的方式。 协程需隶属于某 CoroutineScope ,以实现structured-concurrency,而 CoroutineScope 应
205 0
|
Python
Python编程:类的实例动态增加属性和方法
Python编程:类的实例动态增加属性和方法
172 0
【Groovy】MOP 元对象协议与元编程 ( Expando 动态类 | 创建动态类 | 为动态类增加字段和方法 )
【Groovy】MOP 元对象协议与元编程 ( Expando 动态类 | 创建动态类 | 为动态类增加字段和方法 )
240 0
【Groovy】MOP 元对象协议与元编程 ( Expando 动态类 | 创建动态类 | 为动态类增加字段和方法 )
|
关系型数据库 MySQL
python-面向对象(绑定方法与非绑定方法)
一、绑定方法: 绑定给谁就应该由谁来调用,谁来调用就会将谁当做第一个参数传入   1.绑定给对象的方法:类中定义的函数默认就是绑定给对象的   2.绑定给类的方法:为类中定义的函数加上一个装饰器classmethod 二、非绑定方法: 即不与类绑定,又不与对象绑定,意味着对象和类都可以来调...
1457 0