Delphi高手突破第二章(2),对象大小,类方法与类引用,错误的面向对象设计

================Delphi对象所占内存空间大小==============================
对象所占的内存空间大小取决于这个对象中的数据成员,加上一个4字节的VMT,成员函数不占空间。
注意:编译器对于无法合并的小于32位空间的数据域填充到32位大小,以加快存取速度。所以两个16位的word会被合并成一个integer。但一个单独16位的word会被扩展成一个integer

procedure TForm1.Button1Click(Sender: TObject);
var
Obj : TMyClass;
begin
Obj := TMyClass.Create();
with memo1.Lines do
begin
Add('对象大小:' + IntToStr(Obj.InstanceSize));
Add('对象所在地址 :' + IntToStr(Integer(Obj)));
Add('FMember1所在地址:' + IntToStr(Integer(@Obj.FMember1)));
Add('FMember2所在地址:' + IntToStr(Integer(@Obj.FMember2)));
Add('FMember3所在地址:' + IntToStr(Integer(@Obj.FMember3)));
Add('FMember4所在地址:' + IntToStr(Integer(@Obj.FMember4)));
end;
Obj.Free();
end;


======================类方法和类引用================================

1. 定义类方法(静态方法),它无法操作对象的数据成员,加上class关键字:
class function TObject.ClassName: ShortString;
构造函数 create其实就是一个类方法。

2. 定义类引用(元类,更抽象):
TMyClass = class;
TMyClassClass = class of TMyClass; // TMyClassClass就是类引用

用法:
TMyClass = class;
public
class procedure Show(); // 类方法
end;
TMyClassClass = class of TMyClass;
var
MyClass : TMyClassClass;
MyObj: TMyClass;
begin
MyObj := MyClass.Create();// 注意:引用类MyClass直接调用了类方法。其作用与MyObj := TMyClass.Create(); 完全相同
MyClass.Show();
MyObj.Free();
end;

主要用作类型参数化上,因为有时候在编译时无法得知某个对象的具体类型,而要调用其类方法(如构造函数),此时可以将类型作为一个参数来传递。
比如:Application.CreateForm(TForm1, Form1);

procedure TApplication.CreateForm(
// TComponentClass = class of TComponent; 类引用类型
InstanceClass: TComponentClass;
var Reference
);
允许在运行期确定类型,可以给程序带来莫大的灵活性。

3. Self代表类,因此可以调用类方法,但不能访问对象数据成员
class function ClassMethod1(): integer;
调用的时候可以 self.ClassMethod1();

====================面向对象的错误用法==================================

1. 定义一堆系统函数在一个类里。
其实它什么都没有封装,只是一堆函数的集合而已,是一个没有状态(数据成员)的类。
它不是活的,它所生成的每个对象之间没有任何差别。
2. 如果只有Get/Set函数的类,还是称不上类。
虽然状态是活的,但实际上什么没有隐藏任何东西,也没有简化任何东西。这样的类与record没有任何区别。

什么是设计优良的类?
一个文件操作类:具有状态信息,接口简单、明了、易用。它封装了所有对文件操作的算法,客户端程序不必限于复杂的文件操作的代码中。

原文地址:https://www.cnblogs.com/findumars/p/2628994.html