📄 192.txt
字号:
日月光华 -- SE精华区文章阅读
--------------------------------------------------------------------------------
发信人: LiJohn (永久), 信区: SE
标 题: [转载][zz]OOP语言技术比较:Java,C++,Object Pascal
发信站: 日月光华 (2003年04月10日19:14:31 星期四), 站内信件
【 以下文字转载自 VCL 讨论区 】
【 原文由 aworm 所发表 】
OOP语言技术比较:Java,C++,Object Pascal
http://www.marcocantu.com
本文将主要涉及三种面向对象语言:Internet上最流行的语言Java,最常见的OOP语言C
++,以及Borland公司用于他们的集成开发环境Delphi中的Object Pascal。这三种语言
具有很多相同点。本文将从多个技术角度对这三种语言进行深入研究,并逐一比较。至
于哪一种语言最优秀,我不想做过多的评论,这在很大程度上取决于你究竟要做什么。
本文假定你基本掌握了所涉及的三种语言中的一种,或者至少大体上对OOP概念有一定的
了解。我将会描述一些重要的语言特性,然后我会对三种语言的实现作一个比较。我不
打算举实际的例子,我并不是要教授OOP,只是比较这些语言。
OOP关键特性
面向对象程序设计(OOP)并不是一种新的程序设计技术。它最早可以上溯到Simula-67
,虽然它的第一个真正完整的实现是Simula-80。在80年代下半期,OOP变得流行起来,
并且出现了许多支持OOP的语言,比如C++,Objective-C(另一种C语言扩展),Object
PAscal和Turbo Pascal,CLOS(Lisp的面向对象扩展),Eiffel,Ada(其最新的版本
),以及最近的Java。本文将集中讨论C++、Object Pascal和Java,并有限的设计其它
OOP语言。
OOP的关键特性是广为人知的,在继续下面的内容之前,我将简单的重复一下,以便你再
熟悉一下这些通用技术。
·第一个关键特性是定义了类,封装了表现和操作的抽象数据类型。在OOP语言中,类是
模块、封装和数据抽象的基础。
·第二个关键特性是继承,从已存在的类型中继承元素(表现和方法),改变或扩展旧
类型的方法。
·第三个关键技术被称为多态性,它允许使用类似的方法操作不同类型的对象(通常是
子类对象)。它使得类的可用性进一步提高,程序也因此更容易维护和扩展。
一种语言如果是面向对象的,必须具有类、继承和多态这几个特性(仅支持类而不支持
继承和多态的语言,通常被称为基于对象的)。不同的OOP语言可能会使用完全不同的方
法实现以上几个特性。我们可以通过比较类型检查机制、对不同程序设计模型的支持以
及所支持的对象模型来区别不同的OOP语言。下面我将深入语言特性的细节。
编译期类型检查 vs. 运行期类型检查
类型的强壮性是评价程序设计语言的重要标准。涉及到类型检查的内容包括对已存在的
方法的调用,方法的参数的类型,数组边界的检查,等等。
C++、Java和Object Pascal多或多或少的支持编译期类型检查,其中,C++的类型检查最
弱,而Java的最强。原因是,C++保留了对C语言的支持,而C语言虽然支持编译期类型检
查,却极其微弱。例如,C和C++认为所有数字类型都是兼容的(虽然向整型变量赋浮点
数值时编译器会报警)。在Object Pascal和Java语言中,布尔值与整型数值不同,而字
符类型则是另一个完全不兼容的类型。
虽然Java虚拟机在运行期“翻译”比特码,但并不表示它放弃了编译期类型检查。相反
,在Java中类型检查进行的相当彻底。另外一些OOP语言,例如Smalltalk和CLOS,则在
运行期进行类型检查。
混合OOP语言 vs. 纯OOP语言
另一个区别存在于纯的和混合的OOP语言之间。纯OOP语言只允许应用一种程序设计模型
:OOP。你可以声明类和方法,但不能使用老式的普通函数、过程和全局变量。
在以上三种语言中,只有Java是纯OOP语言(Eiffel和Smalltalk也是),初看上去纯OO
P是个很好的主意,然而,你最终还是会使用许多静态方法和静态数据。除了语法更复杂
,这与使用全局函数和数据没有任何区别。我个人的观点是,纯OOP语言对于OOP的初学
者非常有帮助,因为他将不得不使用(并学习)面向对象程序设计模型。另一方面,C+
+和Object Pascal都是典型的混合语言,他们允许程序员使用传统的C或Pascal程序设计
方法。
要注意的是,Smalltalk大大扩展了纯面向对象的概念。在Smalltalk中,所有预定义数
据类型,例如整型、字符型,甚至整个语言架构(例如循环指令)都是以对象封装的。
这完全是出于对纯理论的兴趣,因为这样极大的降低了程序的执行效率。Java没有做得
如此绝对,它允许使用传统的,非面向对象的数据类型(虽然它提供了对传统类型的类
封装)。
普通对象模型 vs. 对象引用模型
OOP语言之间存在的第三个主要区别在于它们的对象模型。一些比较传统的OOP语言允许
程序员在栈、堆和静态存储区中创建对象。在这些语言中,一个类的变量(实例)对应
于内存中的一个对象。C++就是这样工作的。
之后的OOP语言倾向于使用另一种模型,称为对象引用模型。在这个模型中,每个对象都
动态的创建于堆中,一个类的变量实际上是一个指向内存中的对象的引用或句柄(技术
上类似于指针的某种东西)。Java和Object Pascal都采用了这种引用模型。我们很快就
会看到,采用这种模型你必须记得为对象分配内存。
类、对象和引用
·特性描述:在介绍了以上内容后,我们进入对OOP语言的讨论。最好的起点是类和对象
。我希望每个人都清楚的明白这两个名词的区别,简言之,一个类是一种数据类型,而
一个对象则是某个类的实例。现在我们来看看如何在基于不同对象模型的OOP语言中使用
对象。
·C++:在C++中,假设有一个类MyClass,这个类有一个方法MyMethod,我们可以写出如
下代码:
MyClass Obj;
Obj.MyMethod;
这样就创建了一个名为Obj的MyClass类。通常C++会在栈中为这个对象分配内存空间。现
在就可以像第二行代码那样使用对象了。
·Java:在Java中,类似的语句只为指向对象的句柄分配内存,而不是为对象本身:
MyClass Obj;
Obj = new MyClass();
Obj.MyMethod();
在你使用对象之前,必须使用“new”为对象分配内存。当然,最好在同一条语句中声明
并初始化对象,以避免使用未被初始化的对象句柄:
MyClass Obj = new MyClass();
Obj.MyMethod();
·OP:Object Pascal采用大致相同的方法,但是必须在不同的语句中声明和初始化对象
:
var
Obj: MyClass;
begin
Obj := MyClass.Create;
Obj.MyMethod;
·注意:虽然对象引用模型似乎需要程序员写更多的代码,但要知道,在C++中经常需要
使用对象的指针和引用(例如只有使用指针或引用,才能获得多态性能)。而在对象引
用模型中,指针被默认使用,但却被巧妙的隐藏起来。特别是Java中并没有正式的指针
,而事实上,指针无处不在。只不过程序员不能直接控制这些指针,但也因此他们不会
随机访问内存地址,从而使程序更加安全。
回收
·特性描述:一旦你创建并使用了一个对象,就需要销毁它,以避免浪费内存资源。
·C++:在C++中销毁一个储存在栈中的对象是十分容易的。另一方面,要销毁动态创建
的对象就困难多了。有很多解决办法,例如引用计数和智能指针,但是这样增加了复杂
程度。C++程序员的第一印象是使用引用对象模型来解决问题实在是太糟了。
·Java:对于Java来说,这是小事一桩,因为虚拟机会在后台运行碎片收集程序。这使
得程序员轻松不少。但在另一方面,这也影响了应用程序的执行效率。如果没有编写析
构器,可能会在清除代码执行时导致一个逻辑错误。
·OP:在Object Pascal中,没有类似的碎片收集机制。但是Delphi组件支持一种新概念
,属主对象。属主对象将对所有下属组件的销毁负责。这就使对象销毁变得简单明了。
定义新的类
·特性描述:我们已经了解了如何创建已存在的类的实例(对象),我们新的议题是类
的定义。简单说来,一个类是一个方法的集合,而方法是定义在一些局部数据上的操作
。
·C++:下面是一个简单类的C++定义:
class Date {
private:
int dd;
int mm;
int yy;
public:
void Init(int d, int m, int y);
int Day();
int Month();
int Year();
};
下面是其中一个方法的定义:
void Date::Init(int d, int m, int y)
{
dd = d;
mm = m;
yy = y;
}
·Java:Java的语法与C++语法类似:
class Date {
int dd = 1;
int mm = 1;
int yy = 1;
publlic void Init(int d, int m, int y) {
dd = d; mm = m; yy = y; }
public int Day () { return dd; }
public int Month () { return mm; }
public int Year () { return yy; }
}
两者之间最大的不同在于Java的方法代码在声明的同时就定义了(与C++不同,这并不表
示这些函数是内联函数),并且可以同时初始化类的数据成员。事实上,如果你没有初
始化这些数据成员,Java会将所有数据成员初始化为默认值。
·OP:在Object Pascal的类声明语法更接近C++语法,但是仍有很多区别:
type
Date = class
private
dd, mm, yy: Integer;
public
procedure Init (d, m, y: Integer);
function Month: Integer;
function Day: Integer;
function Year: Integer;
end;
procedure Date.Init (d, m, y: Integer);
begin
dd := d;
mm := m;
yy := y;
end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -