Delphi中的类和对象

原创 2002年11月21日 10:06:00

                   谈谈Delphi中的类和对象
1.登不了大雅之堂地理解几个概念
   说到类和对象,我们不能不提及这样几个概念:类,对象,实例。就我个人觉得可
以这样来理解:对象指的是泛称,自然界的任何实体都可以看成一个对象;而类则是
以这些对象某些特征而分成的一系列的种类;实例则是特指属于某一个类的一个对象。
好啦,这些大道理我就不用多说了。不如来一个“背道而驰”的作法,我们用Delphi
code 来阐述这些外国人提出的一些令我们中国人不好理解的概念吧:
var
  ABtn:TButton;
义ABtn是属于TButton类的一个对象,但ABtn不能说是一个实例,因为它还没有
创建,所以我们说这是定义了一个对象,如果说定义了一个实例,多多少少有
些不够确切。:)
begin
  ABtn:=TButton.Create(Self);//创建一个TButton的实例
  ABtn.Caption:='对象';
  ABtn.Free;
end;

2.对象是一个地地道道的指针
   从物理角度来看,对象就是一段地址空间,这段地址空间的标志就是我们定义的
类“变量”。所以我们可以把对象看成一个类的指针。大家知道,要访问一个指针就
必须对指针初始化。对象的既然是一个指针,也必须对它进行初始化。如何初始化呢?
还是说指针的初始化吧。对于一个指针可以有以下两种方法来进行初始化:
(一)直接分配
var
  Pint:^Integer;
begin
  new(Pint);
  Pint^:=12;
  Dispose(Pint);
end;
(二)指向别的已分配空间的变量
var
  Pint:^Integer;
  i:integer;
begin
  i:=12;
  Pint:=@i;
end;
有趣的是,对象这种“指针”也有两种方法初始化
(一)直接分配
var
  AForm:TForm;
begin
  AForm:=TForm.Create(Self);
  AForm.ShowModal;
  AForm.Free;
end;
(二)指向别的已分配空间的实例
var
  AForm:TForm;
begin
  AForm:=Self;
  AForm.Caption:='知道了吗?为什么会这样呢';
end;
file://这个AForm和它所指向的Form实例共用同一段地址单元,所有对AForm操作都将反应
file://到它所对应的Form实例之上。
说到这,我们就很好解释为什么过程(函数)的对象参数传递时,象这样这的格式:
(一)procedure SetEdit(var Edit:TEdit);
    begin
      Edit.Text:='11';
    end;

(二)procedure SetEdit(Edit:TEdit);
    begin
      Edit.Text:='11';
    end;
效果是一样的了。(一)是把一个TEdit实体作为参数引用的形式进行参数传递,(二)是
把一个TEdit的对象“指针”作为参数传递。

3.类可以理解成一种特殊的数据类型
    我们知道数据类型可以进行强制类型转化,类即然可以理解成一种数据类型,那
么它也应该可以进行类类型转。比方如下代码为一个按钮(Button1)的单击事件:
(一)
procedure TForm1.Button1Click(Sender: TObject);
var
  ACaption:String;
begin
  ACaption:=TButton(Sender).Caption;//Sender从TObject转化到TButton
  ShowMessage(Format('You clicked ''%s'' !',[ACaption]));
end;
在这段代码中,Sender是一个TObject型对象,我们把它强制转化为TButton类型。如你
看得不清楚,可以参照一下我们通常的数据类型的转化:
(二)
procedure TForm1.Button1Click(Sender: TObject);
var
  S_Str:String;
  P_Str:PChar;
begin
  S_Str:='I love China!';
  P_Str:=PChar(S_Str);
  S_Str:='';
  S_Str:=String(P_Str);
  ShowMessage(S_Str);
end;
但是在面对对象的程序设计过程中,强调的是安全性,如(一)的强制类型转化存在着不
安全性。如下的代码,依然是写Button1.OnClick事件:
(三)
procedure TForm1.Button1Click(Sender: TObject);
begin
  TCanvas(Sender).Brush.Color:=clRed;
end;
执行一下,就会出错。这样岂不是违背了面对对象的程序设计的宗旨了吗?没有,即然
是类,就应该有类特定的类强制转化方法,改(三)的方法如下:
(四)
procedure TForm1.Button1Click(Sender: TObject);
begin
  (Sender as TCanvas).Brush.Color:=clRed;
end;//用as来转化,as就可以把错误抓住,不会影响程序的正常运行。
说到这我顺便提一下VB吧,如果学过VB的人可能觉得其中的控件数组比较爽,尤其是在
编写象计算器这样的程序时。但Delphi给我们什么呢?答案是Delphi也能快速简洁的开
发出这样的程序。如是操作:在窗体上放一个Edit和十个Button,把Button.Caption分
别设为'0','1','2',...'9',然后写一个按钮的OnClick事件如下:
(五)
procedure TForm1.Button1Click(Sender: TObject);
begin
  Edit1.Text:=Edit1.Text+(Sender as TButton).Caption;
end;
把别的Button的OnClick事件都关联到Button1Click上,运行程序。拍拍手!这样计算器
程序的雏形就具备了。我们用Delphi的类类型转化,开发出来类似VB中的控件数组功能
的程序也是很棒的嘛!:)

4.抽象类和它的实例
    Delphi中有一种类为抽象类,你不能天真的直接为它创建一个实例。如:TStrings
类。如下代码:
(一)
var
  StrLst:TStrings;
begin
  StrLst:=TStrings.Create;
  StrLst.Add('I love Japan!');
  StrLst.Free;
end;
这是不对的。那如何为诸如TStrings这样的抽象类构造实例呢?答案是借助它的非抽
象子类。我们知道TStrings有一个TStringList非抽象子类。我们就可以这样作:
(二)
var
  StrLst:TStrings;
begin
  StrLst:=TStringList.Create;//借助其子类的构造器,对StrLst进行子类化
  StrLst.Add('I love China!');
  StrLst.Free;
end;
(三)
var
  StrLst:TStringList;
begin
  StrLst:=TStringList.Create;
file://放弃吧,不要再用抽象类,完全用它的“儿子”来你的事吧 
  StrLst.Add('I love China!');
  StrLst.Free;
end;

5.类是一种对数据和操作高度的封装机制
(一)数据封装
unit Unit2;

interface
type
  TEmployee=class
  private
    FName:String;
  public
    Constructor Create;
    function  GetName:String;
    procedure SetName(AName:String);
  end;
implementation

{ TEmployee }

constructor TEmployee.Create;
begin
  FName:='BlazingFire';
end;

function TEmployee.GetName: String;
begin
  Result:=FName;
end;

procedure TEmployee.SetName(AName: String);
begin
  FName:=AName;
end;

end.
如上代码,我们就用了一个过程SetName和一个函数GetName对私有变量FName进行完全的
封装。我们要对FName操作就只有这样:
uses
  unit2;
procedure TForm1.Button1Click(Sender: TObject);
var
  AEmployee:TEmployee;
begin
  AEmployee:=TEmployee.Create;
  AEmployee.SetName('Rose');//利用SetName来设置FName
  MessageBox(Handle,PChar(AEmployee.GetName),'Empoyee',0);
  file://用GetName来访问FName
  AEmployee.Free;
end;
(二)操作封装
unit Unit2;

interface
type
  TDivision=Class
  public
    file://多态性让你的程序更据有“柔韧性”
    function GetDiv(Num1,Num2:Double):Double;overload;
    function GetDiv(Num1,Num2:integer):integer;overload;
  end;
implementation

{ Division }

function TDivision.GetDiv(Num1, Num2: Double): Double;
begin
  try
    Result:=Num1/Num2;
  except
    Result:=0;//提供弹形处理机制,处理除数为0情况
  end;
end;

function TDivision.GetDiv(Num1, Num2: integer): integer;
begin
  try
    Result:=Num1 div Num2;
  except
    Result:=0;//提供弹形处理机制,处理除数为0情况
  end;
end;

end.
如上代码我们通过类的多态性机制把除法分别处理成整除和非整除,又通过异常处理屏
去除数为0的情况,从而保证操作的安全性,在调用时,我们就可以这样来:
uses
  unit2;
{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
  Division:TDivision;
  IValue:integer;
  FValue:Double;
begin
  Division:=TDivision.Create;
  IValue:=Division.GetDiv(1,2);
  FValue:=Division.GetDiv(1.0,2);
  IValue:=Division.GetDiv(1,0);
  FValue:=Division.GetDiv(1.0,0);
  Division.Free;
end;
 
6.类是一种代码重用机制
    比方在5中我们想对这个类加上一个GetAdd函数来作加法运算就可以用类的继承。如
下写就可以了:
(一)
unit Unit2;

interface
type
  TDivision=Class
  public
    function GetDiv(Num1,Num2:Double):Double;overload;
    function GetDiv(Num1,Num2:integer):integer;overload;
  end;
type
  TOperation=Class(TDivision)
  public
    function GetAdd(Num1,Num2:Double):Double;
  end;
implementation

{ Division }

function TDivision.GetDiv(Num1, Num2: Double): Double;
begin
  try
    Result:=Num1/Num2;
  except
    Result:=0;
  end;
end;

function TDivision.GetDiv(Num1, Num2: integer): integer;
begin
  try
    Result:=Num1 div Num2;
  except
    Result:=0;
  end;
end;

{ TOperation }

function TOperation.GetAdd(Num1, Num2: Double): Double;
begin
  Result:=Num1+Num2;
end;

end.
这里我们从TDivision继承了一个子类TOperation。TOperation就可以即有TDivsion
公有方法GetDiv,又有自己的独特的方法GetAdd。这是类为我们提供的“鱼和熊掌兼
得”之法。不错吧。:)

iOS-OC中的类与对象

类是一种数据类型 类只存在源代码中,不在某个区 类是结构体的升级,用于定义变量,类一般定义在.m文件中 类的成员变量名前需要加下划线_ 类中可以添加函数 类中能在堆上定义变量,不能定义在栈上(因为栈小...
  • jialiOS
  • jialiOS
  • 2016年05月28日 15:07
  • 133

Java类和对象 详解(二)

上一篇Java类和对象 详解(一)讲解了类和对象的基本概念,定义和使用,以及对象引用传递的初步分析,下面接着来讲其他内容。一、面向对象的封装性封装(encapsulation)又叫隐藏实现(Hidin...
  • wei_zhi
  • wei_zhi
  • 2016年10月07日 17:52
  • 2427

谈谈Delphi中的类和对象

1.登不了大雅之堂地理解几个概念   说到类和对象,我们不能不提及这样几个概念:类,对象,实例。就我个人觉得可以这样来理解:对象指的是泛称,自然界的任何实体都可以看成一个对象;而类则是以这些对象某些特...
  • piantang
  • piantang
  • 2006年09月25日 16:48
  • 562

Java中类与对象的概念区别

 Java是一种面向对象的程序设计语言(Object Oriented Programming:OOP),面向对象的程序设计语言中有类和对象的概念,它们在概念上有什么区别呢?   这往往是一个...
  • xingkongbaobei
  • xingkongbaobei
  • 2014年08月26日 23:29
  • 4815

Python对象及内存管理

对象类型标准类型 Integer、Boolean、Long integer、Floating point real number、Complex number、String、List、Tuple、D...
  • u010171964
  • u010171964
  • 2015年09月09日 14:24
  • 6362

C++中类与对象的讲解(通俗易懂)

概念 描述 类成员函数 类的成员函数是指那些把定义和原型写在类定义内部的函数,就像类定义中的其他变量一样。 类访问修饰符 类成员可以被定义为 public、private 或 pro...
  • songkai320
  • songkai320
  • 2016年07月14日 20:09
  • 13752

Java类和对象 详解(一)

一、面向对象简述面向对象是一种现在最为流行的程序设计方法,几乎现在的所有应用都以面向对象为主了,最早的面向对象的概念实际上是由IBM提出的,在70年代的Smaltalk语言之中进行了应用,后来根据面向...
  • wei_zhi
  • wei_zhi
  • 2016年10月06日 20:48
  • 19245

浅谈 python的类和对象

浅谈 python的类  刚结束了python的方法,开始看类的时候有点迷糊,类的属性和方法,对象的属性和方法,构造函数,传参。下面就一点点来 分析下。   类(Class) 官方给出的解释是 用来...
  • guoxinjie17
  • guoxinjie17
  • 2017年09月05日 13:23
  • 425

关于DELPHI中的类对象以及类指针简单探讨总结。

      最近用DELPHI写程序,发现了DELPHI类对象引用时,有个需要特别注意的地方,故总结如下,与大家分享。有讲的不对的地方,还请不吝斧正。              首先:我们定义一个类,...
  • wbcp2000
  • wbcp2000
  • 2006年11月15日 15:30
  • 2285

C++类和对象总结

类和对象的区别: 类是抽象的,对象是具体的,所以类不占用内存,而对象占用内存; 总之类是对象的抽象,而对象是类的具体事例 假如:类是水果,那么对象就是香蕉…面向对象的三大特点: 封装、继承、多...
  • xiaobingRSQ
  • xiaobingRSQ
  • 2017年05月12日 17:56
  • 899
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Delphi中的类和对象
举报原因:
原因补充:

(最多只允许输入30个字)