http://www.delphibasics.co.uk/Article.asp?Name=Interface

The reason for interfaces
 

Classes that extend another class can be called sub-classes.

For example, you might extend a bicycle class to have mountain bike, and child bike sub-classes.

They inherit a lot of the common functions of the general bicycle class, but add unique features,

such as stabilizer wheel options for the child bike.

You can call bicycle methods, knowing that they apply generally to all types of bicycle.

 
 

This is a traditional, standard use for classes, since the sub-classes are just variations on a theme.

But supposing you had an application where you had bicycle class objects, car objects, washing machine objects and so on.

And in this application, you wanted each such class to have the following method:

 
 
 function IsRecyclable : Boolean;
 

that would let you know if the object contained recyclable materials.

You could define a high-level class containing this method, and define all of the classes from it.

Or you could simply add the method to each sub class.

 
 

Or you could use interfaces.

Interfaces simply tidy up this situation.

By defining an interface that groups these common methods, it sets a standard for all of the classes that implement the interface.

It makes it easier for the programmer to be disciplined in developing the application;

all of the classes have an additional set of methods that are identical.

And Delphi insists that all of the methods in an interface are implemented.

 
 

Going back to the recyclable object scenario, each sub-class inherits common function from its particular parent class.

This describes the basic structure of the sub-class. It also inherits (by implementation) common function that cut across all classes.

 
  An interface example
 

Like many ideas, an example is the best way to illustrate the concepts.

We'll do it in stages to keep things as simple as possible.

 
  First, let us define a car class:
 
 
 
 type
   // Define our Car class
   TCar = class
   private
     carName  : String;
     carAge   : Byte;
   published
     // Car properties
     property Name : String
       read  carName;
     property Age : Byte
       read  carAge
       write carAge;
 
     // Car constructor
     constructor Create(name : String);
   end;
 

This class is defined by default based on TObject

since we have not specified a base class type.

 
  This class has two properties, and a constructor, shown here:
 
 
 
 // Constructor implmentation for the car class
 constructor TCar.Create(name : String);
 begin
   // Save the car name and set default age and miles
   carName  := name;
   carAge   := 0;
 end;
 

Here we set the two properties of the car : its name and age.

The name is passed as a parameter, and we set a default age of 0.

 
  Now we'll define another class - a bicycle class:
 
 
 
 type
   // Define our Bicycle class
   TBicycle = class
   private
     bikeIsMale    : Boolean;
     bikeWheelSize : Byte;
   published
     // Bicycles properties
     property isMale : Boolean 
       read  bikeIsMale;
     property wheelSize : Byte
       read  bikeWheelSize
       write bikeWheelSize;
 
     // Bicycle constructor
     constructor Create(isMale : Boolean; wheelSize : Byte);
   end;
  This class has two properties, and a constructor, shown here:
 
 
 
 // Constructor implmentation for the bicycle class
 constructor TBicycle.Create(isMale : Boolean; wheelSize : Byte);
 begin
   // Save the passed parameters
   bikeIsMale    := isMale;
   bikeWheelSize := wheelSize;
 end;
 

This class is a little different from the car class,

enough to show that we could not have based the car on the bicycle or the bicycle on the car.

 
  Now we'll define an interface that says whether a class object is recyclable:
 
 
 
 type
   // An interface definition
   IRecyclable = Interface(IInterface)
     // A single function supporting the property
     function GetIsRecyclable : Boolean;
     // A single property
     property isRecyclable : Boolean read GetIsRecyclable;
   end;
 

Our interface uses the standard IInterface interface definition as a base.

Interfaces definitions are like class definitions with all abstract elements.

We do not have to declare them as abstract - they are by default.

 
 

This interface adds an isRecyclable property to any class that implements it.

Every class that implements it will have be guaranteed to have exactly the same way of asking if it is recyclable.

This is the power and benefit of interfaces - uniformity across potentially very different classes.

 
  Any class can implement as many interfaces as it wants - it can conform to any global standards in effect.
 
 
 

Note that we must define the property as using a function -

we cannot declare a data field in the interface since interfaces do not contain data.

 
  Now let us change our classes to support this interface definition:
 
 
 
 type
   // Define our Car class
   TCar = class(TInterfacedObject, IRecyclable)
   private
     carName         : String;
     carAge          : Byte;
     carIsRecyclable : Boolean;    // Added to support IRecyclable
     function GetIsRecyclable : Boolean;   // Added for IRecyclable
   published
     // Car properties
     property Name : String
       read  carName;
     property Age : Byte
       read  carAge
       write carAge;
 
     // Added for IRecyclable
     property isRecyclable : Boolean read GetIsRecyclable;
 
     // Car constructor
     constructor Create(name : String);
   end;
 

Note that we place the function used by the interface isRecyclable property in the private section

we only want the caller to use the property.

 
 

(Note by author : when compiling the code, Delphi insists on the presence of the GetIsRecyclable function,

but not on the most important part - the property.

As far as the author can see, this is not enforcing the salient feature of the interface - the property!).

 
 

We have now based our class on the TInterfaceObject class,

which provides some standard support for classes that implement interfaces.

And we have also based our class on IRecyclable, our new interface.

 
  But we must also declare the new GetIsRecyclable function:
 
 
 
 // Car function required for IsRecyclable attribute
 function TCar.GetIsRecyclable : Boolean;
 begin
   Result := carIsRecyclable;
 end;
 

And we must not forget to set this recyclable value.

We'll do it crudely here in the constructor:

 
 
 // Constructor implmentation for the car class
 constructor TCar.Create(name : String);
 begin
   // Save the car name and set default age and miles
   carName         := name;
   carAge          := 0;
   carIsRecyclable := true    // Sets the recyclable indicator
 end;
 

Phew!

But we must do the same to the Bicycle class to show the true effect.

We'll look at complete code defining and using these classes that you can copy and paste into Delphi,

making note to follow the instructions at the start:

// Full Unit code.
// -----------------------------------------------------------
// You must store this code in a unit called Unit1 with a form
// called Form1 that has an OnCreate event called FormCreate. unit Unit1; interface uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, DateUtils; type
// An interface definition
IRecyclable = Interface(IInterface)
// A single function supporting the property
function GetIsRecyclable : Boolean;
// A single property
property isRecyclable : Boolean read GetIsRecyclable;
end; // Define our Car class
TCar = class(TInterfacedObject, IRecyclable)
private
carName : String;
carAge : Byte;
carIsRecyclable : Boolean;
function GetIsRecyclable : Boolean; // Added for IRecyclable
published
// Car properties
property Name : String
read carName;
property Age : Byte
read carAge
write carAge; // Added for IRecyclable
property isRecyclable : Boolean read GetIsRecyclable; // Car constructor
constructor Create(name : String);
end; // Define our Bicycle class
TBicycle = class(TInterfacedObject, IRecyclable)
private
bikeIsMale : Boolean;
bikeWheelSize : Byte;
function GetIsRecyclable : Boolean; // Added for IRecyclable
published
// Bicycles properties
property isMale : Boolean
read bikeIsMale;
property wheelSize : Byte
read bikeWheelSize
write bikeWheelSize; // Added for IRecyclable
property isRecyclable : Boolean read GetIsRecyclable; // Bicycle constructor
constructor Create(isMale : Boolean; wheelSize : Byte);
end; // The definition of the program form
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
private
{ private declarations }
public
{ public declarations }
end; var
Form1: TForm1; implementation {$R *.dfm} // Constructor implmentation for the car class
constructor TCar.Create(name : String);
begin
// Save the car name and set default age and miles
carName := name;
carAge := ;
carIsRecyclable :=true // Sets the recyclable indicator
end; // Car function required for IsRecyclable attribute
function TCar.GetIsRecyclable : Boolean;
begin
Result := carIsRecyclable;
end; // Constructor implmentation for the bicycle class
constructor TBicycle.Create(isMale : Boolean; wheelSize : Byte);
begin
// Save the passed parameters
bikeIsMale := isMale;
bikeWheelSize := wheelSize;
end; // Bicycle function required for IsRecyclable attribute
function TBicycle.GetIsRecyclable : Boolean;
begin
// We'll asy that only male bicycles are recyclable
if self.isMale
then Result := true
else Result := false;
end; procedure TForm1.FormCreate(Sender: TObject);
var
mumsBike : TBicycle;
dadsCar : TCar;
begin
// Instantiate our bike and car objects
mumsBike := TBicycle.Create(false, );
dadsCar := TCar.Create('Nissan bluebird'); // Ask if each is recyclable
if dadsCar.isRecyclable
then ShowMessage('Dads car is recyclable')
else ShowMessage('Dads car is not recyclable'); if mumsBike.isRecyclable
then ShowMessage('Mums bike is recyclable')
else ShowMessage('Mums bike is not recyclable');
end; end.
 The ShowMessage shows the following program output:
Dads car is recyclable
Mums bike is not recyclable

Delphi Interfaces的更多相关文章

  1. Why we need interfaces in Delphi

    http://sergworks.wordpress.com/2011/12/08/why-we-need-interfaces-in-delphi/ Why we need interfaces i ...

  2. 第二章 使用接口(Using Interfaces)-书籍翻译

    PDF预览 下载地址 http://files.cnblogs.com/DKSoft/CodingInDelphi.pdf 1.1. 解耦(Decoupling) All through this b ...

  3. [Delphi] Delphi版本号对照

    VER300    Delphi Seattle / C++Builder Seattle    23    230    (Delphi:Win32/Win64/OSX/iOS32/iOS64/An ...

  4. Delphi的分配及释放---New/Dispose, GetMem/FreeMem及其它函数的区别与相同

    转载自:http://www.cnblogs.com/qiusl/p/4028437.html?utm_source=tuicool 我估摸着内存分配+释放是个基础的函数,有些人可能没注意此类函数或细 ...

  5. Delphi开发的IP地址修改工具

    用Delphi进行开发的,直接修改注册表,需重启电脑后才生效

  6. Delphi XE5教程3:实例程序

    内容源自Delphi XE5 UPDATE 2官方帮助<Delphi Reference>,本人水平有限,欢迎各位高人修正相关错误! 也欢迎各位加入到Delphi学习资料汉化中来,有兴趣者 ...

  7. delphi 保存网页MHT

    delphi 保存网页MHT   uses ADODB_TLB, CDO_TLB, ComObj,MSHTML;{$R *.dfm}{能把网页如 WWW.QQ.COM保存为一个单文件 .MHT但不能把 ...

  8. Delphi GDI+ Library

    GDI+ LibraryThis library enables GDI+ functionality for Delphi 2009 and later. It differs from other ...

  9. Delphi实现HTMLWebBrowser实现HTML界面

    HTML的界面有以下特点:图文混排,格式灵活,可以包含Flash.声音和视频等,实现图文声像的多媒体界面,而且易于建立和维护.另外,HTML的显示环境一般机器上都具备,通常不需要安装额外的软件.当然, ...

随机推荐

  1. android studio修改新项目package名称

    android项目生成APK发布必须保证package唯一.新项目在已有项目基础上修改就必须修改package名称. 操作如下: 1) 在模块(module)上右键选择Refactor->Ren ...

  2. android学习视频(实战项目演练)

    1.基于Android平台实战无线点餐系统(客户端(Client)和服务端(Server))①http://kuai.xunlei.com/d/xmBrDwI8CAAyXVFRa3d②http://k ...

  3. myeclipse 8.5最新注册码(过期时间到2016年)

    myeclipse 8.5最新注册码(过期时间到2016年) 这几天myeclipse弹出注册码过期,去网上一搜,要么已过期,要么就剩一两个月.倒腾了半天,自己申请了几个注册码,给大家分享一下 Sub ...

  4. poj 2185(二维kmp)

    题意:让你求一个最小的覆盖子矩阵. 分析:首先第一点是确定的:那就是这个子矩阵肯定位于左上角,然后按行考虑,求出每一行可能的重复子串的长度,然后取所有行都存在并且长度最短的长度最为最小子矩阵的宽, 最 ...

  5. [转] C#中绘制矢量图形

    无涯 原文 C# 绘制矢量图形 [原创] 近来参与了一个项目,软件主要的功能就是使用C#画矢量图,然后导出到Word.Excel.Powerpoint中,并且能够再次被编辑.以下是我们的解决过程: 首 ...

  6. PHP开发规范

    十.开发规范下面我们讲解 Yii 编程中推荐的开发规范.为简单起见,我们假设 WebRoot 是 Yii 应用安装的目录.1.URL默认情况下,Yii 识别如下格式的 URL: http://host ...

  7. Raspberry Pi3 ~ 搭建开发环境

    关于树莓派的开发环境 纠结了一些时间 ,我的是raspberry Pi 3 mode b 在官网下载 noobs (raspbain 版本)的. 安装完成之后接上显示器 启动系统 然后最初我是想在这个 ...

  8. JavaScript中,{}+{}等于多少?

    最近,Gary Bernhardt 在一个简短的演讲视频“Wat”中指出了一个有趣的 JavaScript 怪癖: 在把对象和数组混合相加时,会得到一些意想不到的结果. 本篇文章会依次讲解这些计算结果 ...

  9. font-size的探究

    整理网上的资料 font字体,用px,em,100%,rem?分什么情况考虑? 我们逐渐意识到,我们用px作为文字大小的单位,已经出现很多问题.最主要是体现在用户不能灵活的控制文字的大小. 对于大多数 ...

  10. Linux文件系统 (Ubunt)

    Linux 文件系统是linux的一个十分基础的知识,同时也是学习linux的必备知识. 本文将站在一个较高的视图来了解linux的文件系统,主要包括了linux磁盘分区和目录.挂载基本原理.文件存储 ...