标签:
本文是为了加强记忆而写,大多数内容都是在编程的日常工作中使用频率不高的东西,但是又十分重要。
1,构造和析构函数:
a,构造函数:
一般基于TComponent组件的派生类,都应该使用overload关键字进行继承,Delphi中的对象没有什么复合的概念,在设计时,从简便的角度出发
一般都设计为耦合性较强,但是使用简单的派生类即可。构造函数不是必写的,除非“复合”这样的对象实现,当省略构造函数时,会由其父类来实现
新对象的建立。下面是几个常用的写法:
constructor TfmBaseScreen.Create(AOwner: TComponent); //由于参数并没有变化,所以这里在声明的时候可以加override而不是overload
begin
inherited; // Create(AOwner) ; //这里的Create默认是可以省略的。
if AOwner is TPanel then
Self.Width :=TPanel(AOwner).Width;
end;
//-------------------------
constructor TfmHuaPianScan.Create(AOwner: TComponent; AQuery: TADOQuery;
AZDCode: string; AMvOutBillCode : string; MoveOutQuery : TADOQuery); //这个声明时需要增加overload说明
begin
inherited Create(AOwner);
FQuery := AQuery; 这里实现的仅仅是私有变量的初始化,其实更多的应用是派生类成员对象的初始化,并需要在析构函数中进行释放。
FZDCode := AZDCode;
FMvOutBillCode := AMvOutBillCode;
FMoveOutQuery := MoveOutQuery;
end;
//-------------------------
Constructor TDllLoader.Create(strDLLName : String); //这是一个基于TObject的类,由于没有任何成员,所以这里Create什么关键字都不需要带。
Begin
FhDLL := LoadLibrary(strDLLName);
ASSERT(FhDLL <> 0);
End;
b,析构函数
析构函数的使用比构造函数要严格一些,一定要在任何时候都使用override,以保证父类内存空间可以正确的释放。
下面是几个析构函数的写法:
Destructor TDllLoader.Destroy(); //虽然函数体内没有inherited但是声明时一定要加上override.
Begin
If FhDLL <> 0 then
begin
FreeLibrary(FhDLL);
End;
end
//-----------------------------------------
destructor TfmTest.Destroy; //窗体类的析构,一定也要在声明的时候增加override.
begin
temp.Free; //成员的释放应该都安排在inherited之前。
inherited;
end;
当然,在窗体类的构造和析构当中,有很多成员管理方式,可以直接通过消息-->事件模式来实现,并不需要引用类及对象设计模式。
直接调用窗体的OnCreate和OnDestroy就可以完成很多事情。
2,类方法及引用类
a,类方法
实现模式很简单,只需要在定义过程或函数时,增加一个class关键字就可以了,它的地位跟C语言中的静态方法的地位是一样的。它所处理的信息都是与类相关,
不能引用对象成员。
下面是TObject中的一个标准的类方法,用来返回一个类名:
class function TObject.ClassName: ShortString;
b,类中类(引用类)
普通类的语法规则是:
类名=class(父类名)
成员描述;
end;
而类中类的语法是:
类名=Class of 父类名
成员描述;
end;
类中类的父类似乎是其一个对象成员,它可以直接调用其父类的类方法,而类中类定义出的对象,其实是一个类。
我们可以在用类中类定义的对象中,使用构造和析构方法,构造方法可以调用对象的Create也可以调用其类中类的Create,
但是,析构函数不能使用类中类的类方法,只能使用其创建对象的析构。这种方法常用于将类作为参数的使用上,方便
在某一个方法之中,对其不明类(但明其祖类)的对象,进行类方法调用。
下面是一个标准使用的例子,这是Vcl中TApplication所带的方法,虽然名称是创建Form,其实对于任何基于TComponent的
对象都是可以创建的,其实现手法就是类中类:
procedure TApplication.CreateForm(InstanceClass: TComponentClass; var Reference);
var
Instance: TComponent;
begin
// Set flag that TCustomForm constructor can read, so it knows if it‘s being
// created as a main form or not (required when MainFormOnTaskbar is True)
FCreatingMainForm := (FMainForm = nil) and InstanceClass.InheritsFrom(TForm);
Instance := nil;
try
{$IF DEFINED(CLR)}
Instance := InstanceClass.Create(Self);
Reference := Instance;
{$ELSE}
Instance := TComponent(InstanceClass.NewInstance); //这里是直接用的TComponent对象赋值一个派生类空间,面向对象是允许的
TComponent(Reference) := Instance; //这里的Reference是一个实参,这句用于指向创建的对象
try
Instance.Create(Self); //NewInstance创建的空间只是分配一片空白区域,这里将其头部区域格式化成TComponent
except
TComponent(Reference) := nil;
raise;
end;
{$IFEND}
if (FMainForm = nil) and (Instance is TForm) then //当系统中还没有明确主窗口时,而创建的对象是窗体对象,则在这里将其自动设置为主窗体。
begin
TForm(Instance).HandleNeeded;
FMainForm := TForm(Instance);
if MainFormOnTaskBar then
SetWindowLong(Handle, GWL_EXSTYLE, GetWindowLong(Handle, GWL_EXSTYLE) or WS_EX_NOACTIVATE);
ChangeAppWindow(Handle, not MainFormOnTaskBar, not MainFormOnTaskBar);
end;
finally
if (FMainForm = nil) and (Instance is TForm) then
TForm(Instance).FCreatingMainForm := False;
end;
end;
类方法中的Self,指的是类本身,而不是对象,所以没办法象普通Self那样使用。
一个类必须创建具有其对象状态的成员,才是有意义的类。在我上一家公司中,见到有人卖弄高深的把全局方法都建立在一个类中,用类实现。
这样的类,既没有其多样的对象,在方法实现时,甚至一点与类相关的东西都没有,还不如建立一个公共方法单元。
一个标准的类,也不能仅仅是对一堆封装成员的Get和Set操作,应该在成员的逻辑处理中,简化其应有的方法,又要保留必要的变化细节。
3,
标签:
原文地址:http://www.cnblogs.com/Murphieston/p/5577836.html