设为首页 加入收藏

TOP

OOP语言技术比较:Java,C++,Object Pascal(三)
2014-11-24 01:15:22 来源: 作者: 【 】 浏览:26
Tags:OOP 语言 技术 比较 Java Object Pascal
这样做。链接器将不得不做更多的工作,因为编译器无法预料一个方法是否在某个模块中被定义。


·OP:在Object Pascal中,源代码文件被称为单元(unit)。单元被分为接口(interface)和实现(implementation)两部分。接口部分包含了类的定义(包括方法的声明),实现部分则包含了声明于接口部分的方法的定义。在接口中编写执行代码是非法的。你可以使用uses子句包含其它文件,以便引用其中声明的类、方法等等。下面的代码包含了一些编译单元的接口:


uses
Windows, Form, MyFile;


·Java:在Java中,每个源代码文件,或者说编译单元之间是完全独立的。你可以把一组编译单元作为一个包的一部分。与其它两种语言不同,在声明类的同时要编写方法实现的代码。当使用import子句包含一个文件时,编译器只读入它的public声明,而不是所有的代码:


import where.myclass;
import where.* // all the classes


·注意:关于被称为名字空间的模块。另一个关键性的区别是Java和OP的编译器可以读入一个已编译文件,并从中提取它的定义,就像你从已编译代码中提取头文件一样。另一方面,C++语言引用名字空间(namespace)来弥补没有模块结构的不足。在Java和OP中,事实上,通常以模块的名字为前缀来解决名字之间的冲突。使用名字空间也可以达到同样的效果,不过它是内建在语言中的。


/静态方法和数据成员
·特性描述:通常OOP语言允许某些方法和数据成员与整个类相关,而不是对象个体。一般的类方法可以通过类的单个对象或类调用。类数据成员是被所有对象共享的数据成员,而不是为每个对象单独创立。


·C++:在C++中,类方法和类数据成员以static关键字声明。类数据成员必须使用一个特殊的声明来初始化,这是缺少模块结构的不足之一。


·OP:OP中只有类方法,使用class关键字声明。而定义于同一单元中的私有全局变量可以发挥类数据成员的作用。


·Java:Java使用和C++相同的关键字static。静态方法经常被使用(甚至有些过分),这是因为在Java中没有全局函数。静态数据成员可以直接在类声明中初始化。


类和继承
·特性描述:类的继承是OOP的根基之一。它可以用来做一般化表述和特殊化表述。关于继承的基础思想是通过修改或扩展现存的类型建立新的类型,换句话说,一个派生类具有基类的所有数据成员和方法,并添加了新的数据成员和方法,还有可能修改某些以存在的方法。不同的OOP语言用不同的名词描述这种机制(derivation,inheritance,subclassing)、被继承的类(基类,父类,超类)和继承的类(派生类,子类,次类)。


·C++:C++使用public、protected和private关键字定义继承的方式,改变继承的方法和数据成员的访问限定类型。虽然public继承最常被使用,但在C++中默认的是private继承。C++是这三种语言中唯一允许多重继承的语言,以后我们还会提到。下面是一个例子:


class Dog: public Animal {

};


·OP:Object Pascal使用一个特殊的语法表述继承,而不是使用关键字,方法是将基类名放入括号中,添加到类声明中。OP只支持C++中所谓public的继承。OP类具有一个通用基类,以后我们会见到。


type
Dog = class (Animal)

end;


·Java:Java使用extends关键字来表述唯一一种继承类型,对应于C++中的public继承。Java不支持多重继承。Java类同样具有一个通用基类。


class Dog extends Animal {

}


·注意:关于基类的构造函数和初始化。在C++和Java中,基类的构造函数具有很复杂的结构。在OP中,初始化基类则是程序员的责任。这个主题比较复杂,所以我不打算进一步讲述。我会把注意力集中在通用基类、基类访问、多重继承、接口、后期绑定以及其它相关的内容。


所有类的祖先
·特性描述:在一些OOP语言中,所有类都直接或间接的派生自某个特定的基类。这个类(通常被称为Object或其它类似的名字)具有所有类共有的基本功能。事实上,所有类都继承自这个基类。因为最初在Smalltalk中便是如此设计的,所以大多数OOP语言采用了这个概念。


·C++:虽然在C++中没有这个概念,但许多应用程序框架引入了通用基类的概念。MFC是个很好的例子,它有一个CObject类。事实上,最初这是十分意义的,因为语言不具有模板特性(以及多重继承特性)。


·OP:每个类都自动的继承自TObject类。因为OP不支持多重继承,所以所有的类构成了一个巨大的派生树。TObject类可以处理RTTI,同时具有其它一些能力。


·Java:如同OP一样,所有的类继承自Object类。这个基类也具有一些有限的功能。


访问基类的方法
·特性描述:当编写一个类方法或者重载一个基类方法时,你经常需要引用基类的方法。而如果方法在派生类中重新被定义,那么使用方法的名字将调用新方法。OOP语言使用不同的技术或关键字解决访问基类方法的问题。


·C++:在C++中可以使用范围操作符(::)引用一个特定的类。你不仅可以访问基类,甚至可以访问继承链中更高层的类。


·OP:Object Pascal使用一个特殊的关键字完成同样的工作:inherited。在关键字后可以加上需要调用的基类方法的名称,或者(在某些情况下),简单的使用这个关键字来访问对应的基类方法。


·Java:Java中使用super关键字完成类似的工作。在Java和OP中,你无法访问更高一级的基类。看起来这似乎限制了什么,但是这样可以通过添加中间类来扩展继承链。同时,如果你不需要基类的功能,你也许可以不从这个基类派生你的新类。


子类兼容性
·特性描述:并不是所有OOP语言都是强类型的,就像我开始提到的,但是这里我们涉及的三种语言都是。这意味着不同类的对象之间是不兼容的。只有一个例外,就是派生类的对象与基类是兼容的(注意:反过来不成立)。


·C++:在C++中,子类兼容性规则只适用于指针和引用,对普通对象则不适用。事实上,不同的对象在所占用的内存不同,所以你不能将相同的内存分配给不同的对象。


·OP:子类兼容性适用于所有对象,因为OP采用了对象参考模型。此外,所有对象都与TObject类型兼容。


·Java:Java的情况与OP完全相同。


·注意:多态性。如同下一节将要描述的,子类兼容性对于实现后期绑定和多态性是十分重要的。


后期绑定(及多态性)
·特性描述:当继承链中不同的类分别重新定义了它们基类的方法,那么如果能够通过一个兼容这些类的对象(感谢子类兼容性)调用合适的类的方法,将是十分有用的。要完成这个工作,编译器需要支持后期绑定,它将不产生一个特定的函数调用,而是在运行期决定了对象的真正类型后,才进行函数调用。


·C++:在C++中,后期绑定只应用于虚拟方法(在调用速度上会有所减慢)。一个在基类中定义的虚拟方法将在它被重新定义时保持这种特性(当然方法的声明必须完全匹配)。一般情况,非虚拟方法并不允许后期绑定。


·OP:在Object Pascal中,后期绑定通过关键字virtual

首页 上一页 1 2 3 4 5 下一页 尾页 3/5/5
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇DisigenPattern设计模式 下一篇面试经历(20):千橡互动猫扑

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: