对于接口:Interface 这个东西还有点模糊,想请大家讲课。(200分)

  • 主题发起人 主题发起人 吴剑明
  • 开始时间 开始时间

吴剑明

Unregistered / Unconfirmed
GUEST, unregistred user!
有这样的例子:
IMMC = interface
['{4B0752D3-7F57-4D1A-80E0-DB9A76492B4A}']
procedure Connect;
end;

TMMC = class(TInterfacedObject, IMMC)
procedure Connect;
end;

不要问他是干嘛用的。我知道这样是实现某个接口的意思,但现在我只想知道,这样写有
什么用途? 什么情况下应该这样写程序? 在这里这个GUID号有什么用途?他也会想COM里
的那样注册到注册表里去吗?如果会,那能否象COM一样被其他应用程序调用这个接口?
请大家详细讲讲,谢谢。
 
还可以写成这样:

var
m : IMMC;
begin
m := TMMC.Create as IMMC;
m.Connect;

end;

遗憾的是,会敲代码,却不知道这样敲有什么好处。:(
 
1.编写COM必须用接口,要间接实现多重继承要接口...
2.同上
3.接口不一定都得有GUID,但是如果用as运算符或者将接口用于COM,则必须有。
4.会的,进程内COM服务器有专门的函数(好象叫DllRegister)来将GUID写入注册表
5.可以,但是这不仅仅需要一个接口,还需要写COM对象和COM服务器以及类型库
 
可我这个程序不是COM啊,只是个普通的EXE程序而已啊。能不能说说在非COM程序里有什么用?
 
打个多重继承的比方:
你有一个接口: I吃掉.他有一个方法(当然是虚拟的)叫 I吃掉.eat
你还有两个类: T水果和T药,都实现了I吃掉接口.
那么你就可以这样写程序
AInterface:=AObjecct as I吃掉;
AInterface.eat;
程序自然会用正确的吃法去解决,而不管你的AObject是水果还是药
 
简单地说,接口就是一个纯虚类,没有任何实现
 
那样的话,直接建立一个T吃掉的类,再搞个虚拟的方法,继承出来也行啊。那为什么还要搞接口?
我现在就不明白接口好在哪里(在一般应用程序中)。
 
简单地说,接口就是一个抽象类,没有任何实现
 
似乎我也拿不出什么好理由来说明接口和类的各自优势.
本来打算说"接口主要用于COM,一般应用程序可以用抽象类实现".
但转念一想,不对TInterfacedObject就是为了在非COM应用中使用接口而诞生的,
Borland这么做一定有他的理由,等待大家的评判吧
 
接口就相当于一种工业标准
接口制定了标准后,就不管类是怎样实现了
 
接口可以实现多重继承,举个图形方面的例子来说,可以定义IColor,IPosition,ISize,IDraw
这几个接口,然后再类中实现多重接口例如:
TMark=class(TInterfacedObject,IColor,IPostion,IDraw);
TSquare=class(TMark,IColor,IPosition,ISize,IDraw);
另外用接口写的东西可以不管你用什么语言都可以调用
 
> 那为什么还要搞接口?
interface 是 Design Patterns 理论所推崇的第一大应用的原则:
Program to an interface and not to an implementation

http://www.delphibbs.com/delphibbs/dispq.asp?lid=596317
 
to 吴剑明:
>>可我这个程序不是COM啊,只是个普通的EXE程序而已啊。
>>那样的话,直接建立一个T吃掉的类,再搞个虚拟的方法,继承出来也行啊。那为什么还要搞接口?
>>我现在就不明白接口好在哪里(在一般应用程序中)。

看来 你还不明白 什么是COM,Why use COM. 以及Delphi 和 COM 的关系
你用某种语言的类 能做到 Object Reuse
but COM 能跨越语言(在Windows平台中)

other Language use a GUID to Call a COM .
 
lha:
不是我没理解。而是你没理解我在问什么。我都再三强调:
“不是COM啊,只是个普通的EXE程序而已”。可你还是给我拉进COM来。
我现在只关心非COM程序里的INTERFACE的作用。
你说的那些俺早就知道乐。

看哪个大哥还有高见。
 
利用接口来实现多重继承,并不一定需要GUID。
 
对于吴剑明的问题,我的回答是这样的---

Borland 把interface 关键字引入 delphi 中形成COM的基础,但他们也可以用于非面向COM
的编程,这时的接口(interface)于COM中的interface没有任何关系,其实接口可以看成一个
抽象类,不能生成他的实例,需要派生类来完成任务.
(注意:所以接口都是从IUNKNOWN直接或间接基础!)

特点和作用:

1:作为协议使用.这比使用单纯的类更加可以体现"强内聚,松耦合"的软件工程设计思想

2:接口是"功能提供者"--FUNCTION PROVIDER,接口只决定提供什么功能,而对怎样完成
功能提供了最大的自由.

3:接口和类比较,功能相对单一,一般都有比较明确的任务

4:Object Pascal 语言不支持多重继承,但是可以通过接口完成多重继承的大多数好处
而不会带来C++中多重继承的副作用!!

3:在软件工程组(有可能跨国际,跨语言)的开发中,接口会被预先定义,这样在模块的装配调
试中,在以后的升级和维护中可以方便迅速完成目标任务.(做为一个PM,我对此深有体会啊!)

请注意,
1:接口和类(可以称为接口类)是紧密相联的,接口是接口类的功能端口,提供给使用者
调用,接口类是接口功能的内在实现.

2:一个接口类可以实现多个接口,也就是说,多个接口可以通过一个接口类来完成.

3:多接口不是多重继承!!!

4:接口可以实现和定义属性.

总之,关于接口的内容很多,有兴趣的可以从Object Pascal Language Guide和BORLAND 新闻组
的COM讨论区得到解答,那里有TEAM-B的高高高手啊,好像Team-B的在招兵哦!

大家一起享受编程的乐趣吧!!!!!!!!!!!


 
对于接口的解释,我用一个例子来解释一下。不知道能不能说清楚。如果对大家又帮助的话。我的目的就达到了。
这个例子不是Delphi的。是用C#写的。但我想一样可以说明问题。
using System;
namespace UCOM.HR{
public interface IJob //定义接口IJob
{
double ComputeSatary();//定义接口函数
}
public interface IInsurance//定义接口IInsurance
{
double ComputeGinBouFee();//定义接口函数
}
public class Employee : IJob,IInsurance//定义类Employee 并实现前面的两个接口
{
public Employee(string EmpID,double BaseSalary)//定义类Employee构造函数
{
//该构造函数初始化该类中的两个成员变量
mstrEmpID=EmpID;
mdbIBaseSalary=BaseSalary;
}
public virtual double ComputeSatary()//实现接口函数
{
return mdbIBaseSalary;
}
public virtual double ComputeGinBouFee()//实现接口函数
{
return mdbIBaseSalary * 0.01;
}
//一下是该类的成员函数
public void SetEmpID(string EmpID)
{
mstrEmpID=EmpID;
}
public string GetEmpID()
{
return mstrEmpID;
}
//定义该类的成员变量
private string mstrEmpID="";
private double mdbIBaseSalary=0;
}
public class Sales:IJob,IInsurance //定义类Sales实现接口
{
public Sales(string EmpID,double BaseSalary,
double Bonus)//该类的构造函数
{
mstrEmpID=EmpID;
mdbIBaseSalary=BaseSalary;
mdbIBonus=Bonus;
}
public virtual double ComputeSatary()//实现接口函数
{
return mdbIBaseSalary + mdbIBonus;
}
public virtual double ComputeGinBouFee()
{
return mdbIBaseSalary * 0.01;
}
//定义成员函数
public void SetEmpID(string EmpID)
{
mstrEmpID=EmpID;
}
public string GetEmpID()
{
return mstrEmpID;
}
//定义成员变量
private string mstrEmpID="";
private double mdbIBaseSalary= 0;
private double mdbIBonus=0;
}
public class HumnaResource//定义类HumnaResource
{
//定义一接口为形参的函数,接口的优势就在这。当调用这个函数的时候,只要把实现该接口的
//类作为参数传进来,接口就会知道应该调用那个类中的函数,来实现函数的功能。而不用借口
//的话你就必须为每一个类定义一个这样的函数。而定义的这些函数的不同之处就是形参事各个
//类。下面的Main()函数,实现了对这个函数的调用。
public static void ProcessSalary(IJob e)
{
Console.WriteLine("薪金={0}",e.ComputeSatary());
}
public static void ProcessGinBouFee(IInsurance e)
{
Console.WriteLine("保健费={0}",e.ComputeGinBouFee());
}
public static int Main()
{
Employee e = new Employee("001",5000);//创建类(她实现了上面作为形参传入的借口中的函数)
Console.WriteLine("员工={0}",e.GetEmpID());
ProcessSalary(e);//将创建的类传入前面定义的函数中,接口就会自动调用Employee类中的接口函数。
//下面的代码我就不必解释了。
ProcessGinBouFee(e);
Sales s=new Sales("001",5000,1000);
Console.WriteLine("员工={0}",s.GetEmpID());
ProcessSalary(s);
ProcessGinBouFee(s);
return 0;
}
}
}

不知道我的解释对大家有没有帮助。我希望有帮助。
 
通过接口可以完成C++中多重继承的功能。
你可以调用通过INTERFACE声明的变量中的方法,而不用在乎它在哪里实现,怎样实现。
如果只是在APPLICATION而不是在COM中,你不必加入TGUID。
INTERFACE最主要的思想就是一旦公布就不可改变,并且只有说明而不实现。

 
后退
顶部