主题:【原创】JAVA和C#,武当和少林之争! -- Highway
delegate指用其它的对象来完成某功能,比如可以用传入函数指针。
interface则指类需要实现的某些方法,所有实现该接口的类都必须实现这些方法。
个人感觉很多地方用起来比接口方便,对现有代码的侵入也小多了
理解了它也就明白了什么叫“委托”。本来decoration这个设计模式有一个别名就叫delegation的。
除了指针,C++也有reference。C++里引入了reference似乎是想弥补C指针的种种缺陷,但reference本身却不是lvalue,无法完全替代指针。
我感觉Java、C#等“高级编程语言”其实脱离不了C的阴影。这个阴影就是指针。虽然各家都说自己的reference是如何与C指针不同的,但骨子里,都是一嘛事。
为什么呢?现在的计算机体系结构决定的。程序运行时,代码和数据必须在计算机内存里。对象是什么?封装好的数据加代码。要放在内存里就必须占一个地址,并且每个对象占用的地址还必须是唯一的。即使是stateless objects也需要地方来存放自己的类型信息,更别说那些stateful objects的成员变量了。这样,对象就和内存地址有了某种一对一的对应关系:一个对象的reference(或id等任何其他叫法)都是内存地址的一个一一映射函数。
内存地址和C的指针有区别么?没有。
为什么没有人提醒IBM,IBM为什么又不改个名,就不得而知了。
未必符合C#的规则,但我觉得广义上概括了delegate和interface的基本含义。
http://www.yesky.com/338/1930338.shtml
IBM跟SUN争java的领导权也不是一天两天了。
这两个概念同managed code关系不大,基本上还是OO的概念。
delegate是指一个class object调用另一个class object的功能来提供自己的功能。本质上是Composition(或Containment,Layer)。
interface是指提供与parent class相同的接口。本质上是Public-Inheritance.
这就牵涉到OO的几个fundimental的观点。OO的基本教义派认为,
1)Public-Inheritance是严格的IS-A关系,也就是说如果两者是公共继承关系,derived class必须拥有parent class的所有特性。All or None, 要么继承所有接口和功能(derived class可以override parent class的virtual method),要么就不能继承。换言之,parent class必须是derived class的一个子集。
一个著名的例子就是,长方形(rectangle class)同正方形(square class)不存在Public-Inheritance关系,虽然数学上后者是前者的特殊情况,因为正方形(4边一样长)同长方形的长宽可以不一样长的特性矛盾,所以他们不是IS-A关系。
因此,Public-Inheritance是很严格的,按照Scott Meyers和Herb Sutter的说法,除非是严格的IS-A关系(而不是IS-ALMOST-A),不应该使用Public-Inheritance。
2)然而现实世界,具体编程的时候,往往大部分情况下,两个class object之间不存在这种IS-A关系,而常常是一个class需要用到另一个class的某些功能,或两个class拥有某些相同功能,一个class可以利用另一个class的相同功能来实现。这种情况下一般有两种方法,一种就是Composition,即HAS-A关系。一个class object包含另一个class object,通过调用被包含的那个object的功能来提供自己的功能,这种方法叫做delegate。另一种方法叫做Private-Inheritance。
3)除了Composition的HAS-A关系外,class object之间还有一种IS-IMPLEMENTED-IN-TERMS-OF关系,就是两个class的某些功能相同,你希望利用一个class现存的功能来完成另一个class的功能。这种关系当然可以通过Composition来实现,也可以通过Private-Inheritance来实现。一般而言,私有继承目的在于继承parent class的功能而不是Interface,所以很少需要override parent class的method(但不绝对)。
Composition同Private-inheritance本质上没有多大区别,都能够达到相同的目的,然而几乎所有的C++ experts都prefer composition to private-inheritance。具体原因这里就不细说了,请参阅Scott Meyers的Effective C++。一个重要原则是凡是能用Composition的地方绝不要用private-inheritance,除非是不得不如此(比方说你的derived class需要用到parent class的一些protected member)。
由此可见,在具体编程中,delegate(Composition)的使用频度大大超过interface(Public-Inheritance)。而在不存在严格IS-A关系的情况下,用Public-Inheritance来替代Compositon,本质上是violate the fundimental laws of OO Programming的,虽然从功能实现角度上讲毫无问题。
我感觉着poorfat是问的一个非常实际的编程问题,不是想澄清OO的概念。
在.NET中,delegate是一个关键字,interface也是。而在Java中则没有delegate这么个东西。
这两个东西人们之所以放在一起比较是因为他们分别是.NET和Java里面Handle event(以及Callback)的核心机制。Event-driven是现代计算机语言的一个必不可少的东西。在具体实现这一点上,Java和.NET区别很大。等过两天我想和大家聊聊这个问题,如果可能的话连Function Pointer也一起捎带上。
Java从没做过,C#/DotNet刚开始涉及时间不长,倒是写了N年的C++,现在还在写。继续班门弄斧。
我个人感觉delegate更自然和强大灵活一些。
delegate相当于函数指针,但又是type safe的。我的理解是等于把函数当作object用,有点像把STL里的Functor抽象出来加了个关键词。
Interface没什么新鲜的,本质上就是abstract class(在C++/COM中是用pure virtual function实现的)。C#这里抄了Java的,Single-inheritance, multiple interfaces。
Interface是通过override interface来实现callback的,caller利用Interface的method callback,而callee则会调用具体的concrete class中被overidden的method(你自己的实现)。delegate是直接调用另一个函数,更简洁明了。
回到概念问题,为了callback,不得不extend interface,而有时候这两者没有IS-A关系,只能说是一种从权。相反delegate更自然,直接给出一个函数当作object使用,并克服了C/C++中函数指针的缺点。
还有一个区别,Interface对于每个具体的concrete class只能有一个实现,而delegate可以有多个,还可以dynamic,所以后者更强大一点。
指从功能上说。Java里面的anonymous inner class实际上就是delegate。只不过Java增加inner class的时候,已经很难再改JVM Spec,所以要在编译器这一层把inner class都转换成一般的class,所以编译后一大堆分开的class,看起来怪怪的。
另外AOP里面的mixin实际上也是提供实现delegate的另一种方便途径。
delegate实际上是对只有一个method的interface和其实现的一种简化写法。我个人认为delegate是非常方便的,象Groovy这些基于Java的script languages都在考虑或者已经实现enclosure--实际上是delegate的更为强大的变种。不过Java本身再加delegate不太容易了,也不一定有好处,因为delegate被滥用的可能性太大了--大家都把函数传来传去,对class这一层的设计注意力自然会降低。