重温Delphi之:面向对象

任何一门语言,只要具备了"封装,继承,多态"这三项基本能力,不管其实现方式是直接或曲折、复杂或简洁,就可以称之为“面向对象”的语言。

Delphi当年的迅速走红,是以其RAD快速开发吸引程序员的目光。这无疑是它最吸引人的优势,但同时也让人误以为delphi只是vb的高级版本,从而忽视了其面向对象的特性。

其实Pacscal发展到Delphi,已经完全具备了面向对象的所有特点:允许自定义类,类可以继承(单继承),允许方法重载/覆写,可以定义接口,类可以实现接口,允许定义静态方法(即class方法),虚方法,抽象类...等等,对于delphi怀有偏见的朋友,你还会怀疑delphi的面向对象能力吗?

下面是一些演示代码:
1.先定义一个基类TPeople

unit UPeople;

interface

type
  TPeople = class(TObject)

  private
    _name:string; //私成成员定义
    procedure Set_Name(value:string);//Name属性的set方法定义
    function Get_Name:string; //Name属性的get方法定义

  protected
    function Get_Sex:Boolean;virtual;abstract; //定义抽象虚方法,由子类去实现

  public
    property Name:string read Get_Name write Set_Name; //定义Name属性
    property Sex:Boolean read Get_Sex; //定义Sex只读属性(该属性并未实现,而是交由子类去实现)
    class function ToString:string; //类方法,有点象c#中的static静态方法
    procedure ShowName;//公用实例方法
end;

//实现部分
implementation

    procedure TPeople.Set_Name(value:string);
    begin
      _name := value;
    end;

    function TPeople.Get_Name:string;
    begin
      result := _name;
    end;

    class function TPeople.ToString:string;
    begin
      result :=  ‘This is a People Class‘;
    end;

    procedure TPeople.ShowName;
    begin
      Writeln(‘姓名:‘ + _name);
    end;
end.

2.再定义一个子类TMan

unit UMan;

interface

uses
     UPeople ;

type
  TMan = class(TPeople)

  constructor Create(name:string); overload ; //重载构造函数

  private
    _sex:Boolean;

  protected
    function Get_Sex:Boolean; override;

  public
    function ToString:string; //实例方法

  end;

implementation

  constructor TMan.Create(name:string); //注意写法:实现的时候不用加overload关键字
  begin
     inherited Create;
     _sex := true; //男性强制定义为true
     Self.Name := name;

  end;

  function TMan.Get_Sex:Boolean;
  begin
    result := _sex;
  end;

  function TMan.ToString:string;
  begin
    result := ‘这是TMan中的ToString方法‘;
  end;

end.

3.再来一个子类TWoman

unit UWoman;

interface

uses
     UPeople,UICook;

type
  TWoman = class(TPeople,ICook)

  constructor Create(name:string); overload ;

  private
    _sex:Boolean;

  protected
    function Get_Sex:Boolean; override;

  public
    procedure Cook;//接口的方法实现定义
    procedure ShowName;overload;

    //如果Class是从TObject继承的,又想实现接口的话,必须实现下面这三个function,
    //如果想偷懒的话,把UPeople改成从TInterfacedObject继承就可以省掉这个步骤了
    function _AddRef:Integer; stdcall;
    function _Release:Integer;stdcall;
    function QueryInterface(const IID:TGUID;out Obj):HResult; stdcall;
  end;

implementation

  function TWoman._AddRef:Integer;
  begin
      result :=-1;
  end;

  function TWoman._Release:Integer;
  begin
      result :=-1;
  end;

  function TWoman.QueryInterface(const IID:TGUID;out Obj):HResult;
  const
      E_NOINTERFACE = $80004002;
  begin
      if   GetInterface(IID,Obj) then
          Result := 0
      else
          Result := -1; {E_NOINTERFACE}
  end;   

  constructor TWoman.Create(name:string);
  begin
     inherited Create;
     _sex := false;
     Self.Name := name;
  end;

  function TWoman.Get_Sex:Boolean;
  begin
    result := _sex;
  end;

  procedure TWoman.ShowName;
  begin
    Writeln(‘女人总是喜欢搞点花样,所以重载一下哈.‘)
  end;

  procedure TWoman.Cook;
  begin
    Writeln(‘因为我实现了ICook接口,所以我会做饭:)‘)
  end;

end.

注意,TWoman这个子类实现了接口ICook,其定义如下:

4.ICook接口

unit UICook;

interface

type
  ICook = interface //定义一个接口
  procedure Cook;//接口的方法定义
  end;

implementation

end.

5.放到ConsoleApplication中测试一把:

program ClassDemo;

{$APPTYPE CONSOLE}

uses
  SysUtils,
  UPeople in ‘UPeople.pas‘,
  UMan in ‘UMan.pas‘,
  UWoman in ‘UWoman.pas‘,
  UICook in ‘UICook.pas‘;

var
  aPeople:TPeople;
  aMan:TMan;
  aWoman:TWoman;
  aCook:ICook;

begin
  aPeople := TPeople.Create;
  aPeople.Name := ‘jimmy.yang‘;
  Writeln(aPeople.Name);
  Writeln(TPeople.ToString);//调用静态方法
  aPeople.ShowName;

  Writeln(‘----------------------------------------‘);

  aMan := TMan.Create(‘杨俊明‘);
  Writeln(aMan.Name);
  Writeln(aMan.Sex);
  aMan.ShowName; //通过继承得来的方法
  Writeln(aMan.ToString);//TMan实例中的对象方法

  Writeln(‘----------------------------------------‘);

  aWoman := TWoman.Create(‘小龙女‘);
  Writeln(aWoman.Name);
  Writeln(aWoman.Sex);
  aWoman.ShowName; //调用重载后的方法
  aWoman.Cook;//实现接口得来的方法
  Writeln(‘----------------------------------------‘);
  aCook := ICook(aWoman);//类还可以转化为接口
  aPeople.Free;
  aPeople:= TWoman.Create(‘翠花‘); //同样也允许子类创建得到父类
  aPeople.ShowName;
  aWoman.Free;
  aWoman := TWoman(aPeople);
  aWoman.Cook;
  Readln;
end.

运行结果:
jimmy.yang
This is a People Class
姓名:jimmy.yang
----------------------------------------
杨俊明
TRUE
姓名:杨俊明
这是TMan中的ToString方法
----------------------------------------
小龙女
FALSE
女人总是喜欢搞点花样,所以重载一下哈.
因为我实现了ICook接口,所以我会做饭:)
----------------------------------------
姓名:翠花
因为我实现了ICook接口,所以我会做饭:)

时间: 2024-10-11 16:25:20

重温Delphi之:面向对象的相关文章

重温delphi之控制台程序:Hello World!

原文:重温delphi之控制台程序:Hello World! 这二天用c#开发ActiveX时,发现不管怎么弄,c#就是没办法生成ocx的纯正activeX控件,而且还要强迫用户安装巨大的.net framework(我只是想做一个简单截屏功能的activeX整合到silverlight聊天室中),于是想起了曾经用过一年的delphi,虽然时过境迁,现在早以是.net的天下,但是不可否认,delphi仍是win32原生程序最佳的开发工具之一. 关于Delphi的语法学习,可以参见这个chm文档,

Delphi的面向对象编程基础笔记

1.面向对象.一门面向对象的编程语言至少要实现以下三个OOP的概念 封装:把相关的数据和代码结合在一起,并隐藏细节.封装的好处是利用程序的模块化,并把代码和其他代码分开 继承:是指一个新的类能够从父类中获取属性和方法,这种概念能够用来建立VCL这样的多层次的对象,首先建立通用对象,然后创建这些通用对象的有专用功能的子对象.继承的好处是能够共享代码 多态性:从字面上看,是指多种形状.调用一个对象变量的方法时,实际被调用的代码与实际在变量中的对象的实例有关. 2.Object Pascal不像C++

重温delphi之:如何将Bitmap位图与base64字符串相互转换

先引用delphi自带的单元 uses EncdDecd; 然后就可以使用下面二个函数了: by 菩提树下的杨过 http://yjmyzz.cnblogs.com/ ///将Bitmap位图转化为base64字符串function BitmapToString(img:TBitmap):string ;var  ms:TMemoryStream;  ss:TStringStream;  s:string;begin    ms := TMemoryStream.Create;    img.S

Delphi面向对象编程

一.面向对象介绍 OOP是使用独立的对象(包含数据和代码)作为应用程序模块的范例.虽然OOP不能使得代码容易编写,但是它能够使得代码易于维护.将数据和代码结合在一起,能够使定位和修复错误的工作简单化,并最大限度地减少对其他对象的影响,提高代码的性能.一般OOP都支持一下三个概念: 1)封装:把相关的数据和代码结合在一起,并隐藏了实现细节.封装的好处是有利于程序的模块化,并把代码和其他代码分开 2)继承:是指一个新的对象能够从父对象中获取属性和方法,这种概念能用来建立VCL这样的多层次的对象,首先

Delphi 2 Unleashed (一) 介绍

原书作者是作者是 Charles Calvert,国内翻译为<Delphi 2 程序设计大全>,由横空翻译组翻译,机械工业出版社1997年12月出版,看网上评论和介绍,该书是系统学习 Delphi 最好的书籍. 原书 1207 页,也算是一本大块头了,本人有幸收得该书,索性拿起来阅读阅读,并写下一些心得,和大家进行分享. 全书共 7 个部分,分别是: 面向对象的 Pascal,主要介绍 Win32 中的变量.字符串.指针等 Win32,介绍了 Win32 中多任务多线程和内存管理 Window

DELPHI下多线程编程的几个思维误区(QDAC)

有几个网友私下问我一些有关线程的事情.过节写个东西上来大家交流. 思维误区1,自己新建的THREAD是线程,自己的主程序不是线程. 很多人在多线程编程没有把主线程也当作线程.其实主线程也是线程.看起来是废话,这个话确实很重要,这个就意味着,在DELPHI中,不光你开的线程,还有你的主线程所有的内存分配也是串的,进锁排队的.主线程和线程的区别 A.一般来说主线程的优先级高了点.(当然你也可以自己设置) B.主线程在WIN下是处理APPLICATION的消息. 其他基本与你自建线程无区别. 所以这一

Delphi中对象的创建,理解对象名与对象实体的本质区别

2015.08.06我总结的关于New和指针的问题(见此博客),最近在使用Delphi的面向对象的时候,发现很多类似的问题,现在也要总结一下. 目前以下的总结是针对Delphi的,对于C++我还没有实验过. 情况一:对一个对象变量多次Create 首先说一下对象声明的时候 var ObjectA: ClassA; 比如有一个类ClassA,用它来声明一个变量 ObjectA: ClassA; 注意这个时候的ObjectA相当于一个空指针,因为此时并没有创建一个对象实体(参看博客:http://w

Delphi的类与继承

既然已经做出了com程序用delphi来开发的决定,那当然就要对delphi进行一些深入的了解.有人说delphi是一个用控件堆砌起来的工具,和vb没什么两样:也有人说dephi实际上是面向过程的,他的面向对象并不彻底.实际生活中持这两种观点的人不在少数,就拿我认识的一个非常好的程序员来说吧,他很早就开始用vb,到后来接触到delphi,并且用delphi也开发了不少程序,但吃惊的是这些程序全都是面向过程的.我并没有贬低这种做法的意思,我想说的是:好的delphi控件+好的编程规范+优秀的vcl

c#中开发ActiveX的学习笔记

1.为什么要用ActiveX? 网页本身的功能是有限的,要想实现一些网页本身不支持的功能,比如:网页上的p2p视频播放,就得靠ActiveX这种古老的技术. 2.c#能开发ActiveX吗? 严格意义上讲,c#是不能生成纯正ocx控件的,我们在vs.net中新建项目时,也找不到专门的"ActiveX项目"新建项,最多也只就能新建"类库"得到一个dll而非ocx(因此我们也无法用传统的regsvr32来注册该dll),但是c#能开发com组件,activeX控件本质上