找回密码
 注册
搜索
热搜: 超星 读书 找书
查看: 2413|回复: 14

面向对象编程语言的比较:c++,java,delphi

[复制链接]
发表于 2003-12-2 00:00:00 | 显示全部楼层 |阅读模式
面向对象编程语言比较 Java C++和Delphi
Marco Cantu
关键字
本文将主要涉及三种面向对象语言Internet 上最流行的语言Java 最常见的OOP 语言
C++ 以及Borland 公司用于他们的集成开发环境Delphi 中的Object Pascal2 这三种语言具
有很多相同点本文将从多个技术角度对这三种语言进行深入研究并逐一比较至于哪一
种语言最优秀我不想做过多的评论这在很大程度上取决于你究竟要做什么
本文假定你基本掌握了所涉及的三种语言中的一种或者至少大体上对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++ Delphi 和Java 并有限的设计其它OOP 语言
OOP 的关键特性是广为人知的在继续下面的内容之前我将简单的重复一下以便
你再熟悉一下这些通用技术
􀁹 第一个关键特性是定义了类封装了表现和操作的抽象数据类型在OOP 语言中
类是模块封装和数据抽象的基础
􀁹 第二个关键特性是继承从已存在的类型中继承元素表现和方法改变或扩展
旧类型的方法
􀁹 第三个关键技术被称为多态性它允许使用类似的方法操作不同类型的对象通常
是子类对象它使得类的可用性进一步提高程序也因此更容易维护和扩展
一种语言如果是面向对象的必须具有类继承和多态这几个特性仅支持类而不支持
继承和多态的语言通常被称为基于对象的不同的OOP 语言可能会使用完全不同的方法
实现以上几个特性我们可以通过比较类型检查机制对不同程序设计模型的支持以及所支
持的对象模型来区别不同的OOP 语言下面我将深入语言特性的细节
编译期类型检查 vs. 运行期类型检查
类型的强壮性是评价程序设计语言的重要标准涉及到类型检查的内容包括对已存在的
方法的调用方法的参数的类型数组边界的检查等等
C++ Java 和Delphi 都或多或少地支持编译期类型检查其中C++的类型检查最弱
而Java 的最强原因是C++保留了对C 语言的支持而C 语言虽然支持编译期类型检查
1 本文由leasun 译刘艺审校原文参见http://www.marcocantu.com/papers/ooplang.htm
2 从Delphi7 开始Borland 公司将Object Pascal 正式改称为Delphi 语言译文中将Object Pascal 语言统一
称为Delphi 语言
却极其微弱例如C 和C++认为所有数字类型都是兼容的虽然向整型变量赋浮点数值时
编译器会报警在Delphi 和Java 语言中布尔值与整型数值不同而字符类型则是另一个
完全不兼容的类型
虽然Java 虚拟机在运行期翻译比特码但并不表示它放弃了编译期类型检查相
反在Java 中类型检查进行的相当彻底另外一些OOP 语言例如Smalltalk 和CLOS 则
在运行期进行类型检查
混合OOP 语言 vs. 纯OOP 语言
另一个区别存在于纯的和混合的OOP 语言之间纯OOP 语言只允许应用一种程序设计
模型OOP 你可以声明类和方法但不能使用老式的普通函数过程和全局变量
在以上三种语言中只有Java 是纯OOP 语言Eiffel 和Smalltalk 也是初看上去纯
OOP 是个很好的主意然而你最终还是会使用许多静态方法和静态数据除了语法更复
杂这与使用全局函数和数据没有任何区别我个人的观点是纯OOP 语言对于OOP 的初
学者非常有帮助因为他将不得不使用并学习面向对象程序设计模型另一方面C++
和Delphi 都是典型的混合语言他们允许程序员使用传统的C 或Pascal 程序设计方法
要注意的是Smalltalk 大大扩展了纯面向对象的概念在Smalltalk 中所有预定义数
据类型例如整型字符型甚至整个语言架构例如循环指令都是以对象封装的这完
全是出于对纯理论的兴趣因为这样极大的降低了程序的执行效率Java 没有做得如此绝对
它允许使用传统的非面向对象的数据类型虽然它提供了对传统类型的类封装
普通对象模型 vs. 对象引用模型
OOP 语言之间存在的第三个主要区别在于它们的对象模型一些比较传统的OOP 语言
允许程序员在栈堆和静态存储区中创建对象在这些语言中一个类的变量实例对应
于内存中的一个对象C++就是这样工作的
之后的OOP 语言倾向于使用另一种模型称为对象引用模型在这个模型中每个对
象都动态的创建于堆中一个类的变量实际上是一个指向内存中的对象的引用或句柄技术
上类似于指针的某种东西Java 和Delphi 都采用了这种引用模型我们很快就会看到采
用这种模型你必须记得为对象分配内存
类对象和引用
􀂄 特性描述
在介绍了以上内容后我们进入对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();
􀂄 Delphi
Delphi 采用大致相同的方法但是必须在不同的语句中声明和初始化对象
var
Obj: MyClass;
begin
Obj := MyClass.Create;
Obj.MyMethod;
􀂄 注意
虽然对象引用模型似乎需要程序员写更多的代码但要知道在C++中经常需要使用对
象的指针和引用例如只有使用指针或引用才能获得多态性能而在对象引用模型中
指针被默认使用但却被巧妙的隐藏起来特别是Java 中并没有正式的指针而事实上
指针无处不在只不过程序员不能直接控制这些指针但也因此他们不会随机访问内存地址
从而使程序更加安全
回收
􀂄 特性描述
一旦你创建并使用了一个对象就需要销毁它以避免浪费内存资源
􀂄 C++
在C++中销毁一个储存在栈中的对象是十分容易的另一方面要销毁动态创建的对象
就困难多了有很多解决办法例如引用计数和智能指针但是这样增加了复杂程度C++
程序员的第一印象是使用引用对象模型来解决问题实在是太糟了
􀂄 Java
对于Java 来说这是小事一桩因为虚拟机会在后台运行碎片收集程序这使得程序
员轻松不少但在另一方面这也影响了应用程序的执行效率如果没有编写析构器可能
会在清除代码执行时导致一个逻辑错误
􀂄 Delphi
在Delphi 中没有类似的碎片收集机制但是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 会将所有数据成员初始化为默认值
􀂄 Delphi
在Delphi 的类声明语法更接近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;
function Date.Day: Integer;
begin
Result := dd;
end;
你可能注意到一些语法上的区别定义方法使用两个不同的关键字function 和
procedure 没有参数的方法不使用圆括号方法在类定义中声明之后再作定义就像C++
中经常遇到的情况一样注意Pascal 使用点运算符而C++使用作用域操作符::
􀂄 注意
访问当前对象OOP 语言的方法与全局函数不同它包含了一个隐藏参数一个指
向当前被操作对象的指针或引用在不同的语言中这个参数的名字不同在C++和Java
中是this 在Delphi 中是self
构造函数constructor
􀂄 特性描述
上文所述的类实在太简单了为了解决对象初始化的问题我们要为类增加一个构造函
数这也是改进类所需迈出的第一步
􀂄 C++
在C++以及Java 中构造函数和类具有相同的名字如果你没有定义构造函数编译
器会自动为类添加一个默认构造函数在这两种语言中你的类可以具有多个构造函数这
要感谢方法重载
􀂄 Java
在Java 中虽然构造函数也被称为初始化函数initializer 但与C++的构造函数在使
用上没有什么区别需要注意的是Java 虚拟机负责创建对象而构造函数只对创建的对象
进行初始化Delphi 也有类似的情况
􀂄 Delphi
在Delphi 中构造函数以一个特殊的关键字constructor 声明在Delphi 中没有方
法重载3 不过因为构造函数的名字可以任意指定所以你可以提供几个名字不同的构造函
数Delphi 中每个类都有默认的构造函数Create 除非你用名字相同而参数不同的构造
函数将其覆盖这个构造函数继承自一个通用基类下面我们会提到
析构函数和finalize()
􀂄 特性描述
析构函数扮演了构造函数反面的角色通常在对象销毁时被调用如果说大多数类都需
要构造函数那么只有很少的类需要析构函数一个析构函数的基本功能就是释放构造函数
以及对象生存期中的其它方法分配的资源这些资源包括内存文件数据库表Windows
句柄等等
􀂄 C++
C++的析构函数在对象超出作用域时或者删除动态创建对象时自动被调用每个类只
能由一个析构函数
􀂄 Delphi
Delphi 的析构函数与C++的析构函数类似Delphi 使用标准虚拟析构函数称为
Destroy 析构函数通过标准Free 方法调用因为所有对象都是动态创建的所以你
或者对象的属主必须调用对象的析构函数以释放资源理论上你可以定义多个析构函数
不过只有你手动调用析构函数才有些价值没有什么是自动完成的
􀂄 Java
Java 没有析构函数没有引用的对象将被碎片回收程序在后台销毁在销毁对象之前
碎片回收程序调用finalize()方法但是并没有什么保证这个函数真正被调用至少在Java
1.0 中时是这样因此如果你需要释放资源你就要定义一个方法并保证它被调用
类封装Private 和Public
􀂄 特性描述
这三种语言提供了相同的三种访问限定符来提供不同级别的类封装public protected
和private public 意味着对于任何类都是可见的protected 意味着对于派生类可见private
意味着没有外部可见性但是三种语言的实现细节并不相同
􀂄 C++
在C++中你可以使用friend 关键字跳出类封装由class 关键字声明的类默认可见性
是private 由struct 关键字声明的类默认可见性是public
􀂄 Delphi
在Delphi 中private 和protected 关键字只对在不同单元中的类有作用在同一单元源
代码文件声明的类彼此之间可以自由访问Delphi 还有两个特殊的访问限定符published
和automated published 将为类的成员建立RTTI 运行期类型信息automated 用于OLE
自动化接口
􀂄 Java
3原文如此译者
在Java 中一个语法上的区别是每一个类成员都要用访问限定符声明另一个实质上
的区别是Java 中类成员默认访问限定符是friendly 因此对同一个包源代码文件类似
于Delphi 的单元中的所有类都是可见的同样protected 关键字表示类成员对派生类可
见同时也对同一个包中的其它类可见而private protected 才对应于C++中的protected
文件单元和包
􀂄 特性描述
这三种语言的一个重要区别是对源代码文件的组织管理它们都使用文件作为储存源代
码的标准机构与其它OOP 语言如Smalltalk 不同不同的是C++的编译器并不真正了解
文件而Delphi 和Java 则不同它们使用模块概念来管理文件虽然各自的名字不太一样
􀂄 C++
在C++中程序员们一般把类定义放在头文件中而把方法实现放入独立的代码文件
通常这两个文件会具有相同的文件名和不同的扩展名一个编译单元应该包括它自己的声明
文件及其代码所涉及的类及函数的声明文件但这仅仅是惯例编译器并不强迫这样做链
接器将不得不做更多的工作因为编译器无法预料一个方法是否在某个模块中被定义
􀂄 Delphi
在Delphi 中源代码文件被称为单元unit 单元被分为接口interface 和实现
implementation 两部分接口部分包含了类的定义包括方法的声明实现部分则包含
了声明于接口部分的方法的定义在接口中编写执行代码是非法的你可以使用uses 子句
包含其它文件以便引用其中声明的类方法等等下面的代码包含了一些编译单元的接口
uses
Windows, Form, MyFile;
􀂄 Java
在Java 中每个源代码文件或者说编译单元之间是完全独立的你可以把一组编译
单元作为一个包的一部分与其它两种语言不同在声明类的同时要编写方法实现的代码
当使用import 子句包含一个文件时编译器只读入它的public 声明而不是所有的代码
import where.myclass;
import where.* // all the classes
􀂄 注意
关于被称为名字空间的模块另一个关键性的区别是Java 和Delphi 的编译器可以读入
一个已编译文件并从中提取它的定义就像你从已编译代码中提取头文件一样另一方面
C++语言引用名字空间namespace 来弥补没有模块结构的不足在Java 和Delphi 中事
实上通常以模块的名字为前缀来解决名字之间的冲突使用名字空间也可以达到同样的效
果不过它是内建在语言中的
类/静态方法和数据成员
􀂄 特性描述
通常OOP 语言允许某些方法和数据成员与整个类相关而不是对象个体一般的类方
法可以通过类的单个对象或类调用类数据成员是被所有对象共享的数据成员而不是为每
个对象单独创立
􀂄 C++
在C++中类方法和类数据成员以static 关键字声明类数据成员必须使用一个特殊的
声明来初始化这是缺少模块结构的不足之一
􀂄 Delphi
Delphi 中只有类方法使用class 关键字声明而定义于同一单元中的私有全局变量可
以发挥类数据成员的作用
􀂄 Java
Java 使用和C++相同的关键字static 静态方法经常被使用甚至有些过分这是因为
在Java 中没有全局函数静态数据成员可以直接在类声明中初始化
类和继承
􀂄 特性描述
类的继承是OOP 的根基之一它可以用来做一般化表述和特殊化表述关于继承的基
础思想是通过修改或扩展现存的类型建立新的类型换句话说一个派生类具有基类的所有
数据成员和方法并添加了新的数据成员和方法还有可能修改某些已存在的方法不同的
OOP 语言用不同的名词描述这种机制derivation inheritance subclassing 被继承的类基
类父类超类和继承的类派生类子类次类
􀂄 C++
C++使用public protected 和private 关键字定义继承的方式改变继承的方法和数据成
员的访问限定类型虽然public 继承最常被使用但在C++中默认的是private 继承C++
是这三种语言中唯一允许多重继承的语言以后我们还会提到下面是一个例子
class Dog: public Animal {
...
};
􀂄 Delphi
Delphi 使用一个特殊的语法表述继承而不是使用关键字方法是将基类名放入括号中
添加到类声明中Delphi 只支持C++中所谓public 的继承Delphi 类具有一个通用基类以
后我们会见到
type
Dog = class (Animal)
...
end;
􀂄 Java
Java 使用extends 关键字来表述唯一一种继承类型对应于C++中的public 继承Java
不支持多重继承Java 类同样具有一个通用基类
class Dog extends Animal {
...
}
􀂄 注意
关于基类的构造函数和初始化在C++和Java 中基类的构造函数具有很复杂的结构
在Delphi 中初始化基类则是程序员的责任这个主题比较复杂所以我不打算进一步讲
述我会把注意力集中在通用基类基类访问多重继承接口后期绑定以及其它相关的
内容
所有类的祖先
􀂄 特性描述
在一些OOP 语言中所有类都直接或间接的派生自某个特定的基类这个类通常被
称为Object 或其它类似的名字具有所有类共有的基本功能事实上所有类都继承自这
个基类因为最初在Smalltalk 中便是如此设计的所以大多数OOP 语言采用了这个概念
􀂄 C++
虽然在C++中没有这个概念但许多应用程序框架导入了通用基类的概念MFC 是个
很好的例子它有一个CObject 类事实上最初这是十分意义的因为语言不具有模板特
性以及多重继承特性
􀂄 Delphi
每个类都自动的继承自TObject 类因为Delphi 不支持多重继承所以所有的类构成了
一个巨大的派生树TObject 类可以处理RTTI 同时具有其它一些能力
􀂄 Java
如同Delphi 一样所有的类继承自Object 类这个基类也具有一些有限的功能
访问基类的方法
􀂄 特性描述
当编写一个类方法或者重载一个基类方法时你经常需要引用基类的方法而如果方法
在派生类中重新被定义那么使用方法的名字将调用新方法OOP 语言使用不同的技术或
关键字解决访问基类方法的问题
􀂄 C++
在C++中可以使用范围操作符:: 引用一个特定的类你不仅可以访问基类甚至可
以访问继承链中更高层的类
􀂄 Delphi
Delphi 使用一个特殊的关键字完成同样的工作inherited 在关键字后可以加上需要调
用的基类方法的名称或者在某些情况下简单的使用这个关键字来访问对应的基类方

􀂄 Java
Java 中使用super 关键字完成类似的工作在Java 和Delphi 中你无法访问更高一级
的基类看起来这似乎限制了什么但是这样可以通过添加中间类来扩展继承链同时如
果你不需要基类的功能你也许可以不从这个基类派生你的新类
子类兼容性
􀂄 特性描述
并不是所有OOP 语言都是强类型的就像我开始提到的但是这里我们涉及的三种语
言都是这意味着不同类的对象之间是不兼容的只有一个例外就是派生类的对象与基类
是兼容的注意反过来不成立
􀂄 C++
在C++中子类兼容性规则只适用于指针和引用对普通对象则不适用事实上不同
的对象在所占用的内存不同所以你不能将相同的内存分配给不同的对象
􀂄 Delphi
子类兼容性适用于所有对象因为Delphi 采用了对象引用模型此外所有对象都与
TObject 类型兼容
􀂄 Java
Java 的情况与Delphi 完全相同
􀂄 注意
多态性如同下一节将要描述的子类兼容性对于实现后期绑定和多态性是十分重要的
后期绑定及多态性
􀂄 特性描述
当继承链中不同的类分别重新定义了它们基类的方法那么如果能够通过一个兼容这些
类的对象感谢子类兼容性调用合适的类的方法将是十分有用的要完成这个工作编
译器需要支持后期绑定它将不产生一个特定的函数调用而是在运行期决定了对象的真正
类型后才进行函数调用
􀂄 C++
在C++中后期绑定只应用于虚拟方法在调用速度上会有所减慢一个在基类中定
义的虚拟方法将在它被重新定义时保持这种特性当然方法的声明必须完全匹配一般情
况非虚拟方法并不允许后期绑定
􀂄 Delphi
在Delphi 中后期绑定通过关键字virtual 或dynamic 导入这两个关键字的区别仅在
于技术实现的不同在派生类重新定义方法时应使用override 关键字这样就强迫编译
器检查方法声明是否匹配这是Delphi 中特有的它允许在基类做更多的改动
􀂄 Java
在Java 中所有的方法都使用后期绑定除非你使用final 关键字final 方法不能被重
新定义在调用速度上更快在Java 中正确的方法名称对于多态性的实现是非常重要的
Java 中默认后期绑定和C++中默认前期绑定这一事实表明了这两种语言不同的针对性C++
有时会牺牲OOP 模型以获取性能的提升
􀂄 注意
构造函数和析构函数的后期绑定与其它两种语言相反Delphi 允许定义虚拟构造函数
而这三种语言都支持虚拟析构函数
抽象方法和抽象类
􀂄 特性描述
当建立一个复杂的继承链时为了实现多态性经常需要为更高级的类导入一些方法
虽然这些方法未必是为这个类抽象概念而定义的除了使用空方法定义许多OOP 语言实
现了一种特殊的机制定义抽象方法所谓抽象方法就是没有实现的方法具有一个或多个
抽象方法的类称为抽象类
􀂄 C++
在C++中抽象方法被称为纯虚函数通过在方法定义后添加所谓虚定义符=0 可
以获得一个抽象方法抽象类就是具有或继承了一个或多个抽象方法的类不能创建抽
象类对象
􀂄 Delphi
Delphi 使用abstract 关键字声明抽象方法同样抽象类就是具有或继承了抽象方法的
类但是你可以创建抽象类的实例虽然编译器会产生一个警告信息这就隐含了调用抽
象方法的危险在运行期这样会产生一个运行期错误并会终止程序的运行
􀂄 Java
在Java 中抽象方法和抽象类都用abstract 关键字声明事实上Java 中的抽象类必须
具有抽象方法好像有一点多余同样派生类如果没有重新定义所有的抽象方法必须
使用abstract 关键字定义为抽象类不能创建抽象类的实例
多重继承和接口
􀂄 特性描述
一些OOP 语言允许从多个基类派生新类另一些语言只允许从一个类中派生新类但
是可以从多个接口或者纯抽象类只由纯虚函数构成的类派生新类
􀂄 C++
C++是三种语言中唯一支持多重继承的一些程序员认为这是一件好事另一些程序员
认为这是一件坏事我不想过多的讨论这个问题多重继承产生了很多新概念比如说虚基
类虽然功能强大但并不好掌握C++没有接口的概念虽然它与多重继承的纯抽象类概
念接近接口可以看作多重继承的子集
􀂄 Java
Java 以及Delphi 都不支持多重继承但是完全支持接口接口的方法支持多态性
并且当需要一个接口对象时可以通过一个对象实现接口一个类只能继承自一个基类但
可以implement 关键字多个接口Java 的接口与COM 模型非常吻合虽然没有预先的
考虑举个例子
public interface CanFly {
public void Fly();
}
public class Bat extends Animal implements CanFly {
public void Fly( ) { // the bat flies... }
}
􀂄 Delphi
Delphi 3 在Delphi 中导入了类似Java 的接口这些接口非常吻合COM 虽然技术上经
常在非COM 程序中使用接口构造了一个与类独立的继承链但是与Java 一样一个类
可以继承自唯一的基类并实现多个接口将类的方法映射为类实现的接口的方法是Delphi
语言中令人迷惑的几个问题中的一个
RTTI
􀂄 特性描述
在强类型OOP 语言中编译器完成所有类型检查的工作所以很少需要运行程序保存
类型的信息然而某些情况下需要某些类型信息因此这三种OOP 语言都或多或少的
支持运行期类型识别/信息RTTI
􀂄 C++
最初的C++语言不支持RTTI 后来通过dynamic_cast 的方式提供了部分的类型信息
你可以查询一个对象的类型也可以检查两个对象是否具有相同的类型
􀂄 Delphi
Delphi 以及它的可视开发环境支持也需要大量的RTTI 不仅可以进行类型检查使用
is 和as 操作符类也为它的published 成员生成大量的RTTI 事实上这个关键字负责部分
RTTI 的生成属性流结构窗体文件以及始于对象观察器的Delphi 环境很大程度上依赖
于类的RTTI TObject 类具有ClassName 和ClassType 方法ClassType 方法返回一个类类型
变量一个特殊类参考类型的实例并不是类本身
􀂄 Java
和Delphi 一样Java 中也有一个基类用于跟踪类型信息Object 类的getClass()方法会
返回一个元类一个用于描述类的类型的对象你也可以使用getName()函数获得一个类名
字符串你还可以使用instanceof 操作符Java 1.0 不支持更多内容的RTTI 但在未来的版
本中可能会改变以适应可视环境和组件的开发所谓Java Beans
例子
// C++
Dog* MyDog = dynamic_cast <Dog*> (myAnimal);
// Java
Dog MyDog = (Dog) myAnimal;
// Delphi
Dog myDog := myAnimal as Dog;
异常处理
&#1048708; 特性描述
异常处理构想的出发点是简化程序的错误处理代码提供标准内建机制从而使程序更
加健壮异常处理的内容很多这里我只是简述一些关键的要素和区别
&#1048708; C++
C++使用throw 关键字来产生一个异常用try 关键字标志被保护的程序块用catch 关
键字标志异常处理程序代码异常是一些特殊类的对象在这三种语言中都构成了各自的继
承链C++会对所有栈中的对象进行栈展开和销毁调用析构函数
&#1048708; Delphi
Delphi 使用与C++类似的关键字raise try 和except 并且具有类似的功能唯一真正
的区别是因为没有对象会被创建于栈中所以不会发生栈展开另外你可以使用一个finally
关键字标志那些无论是否产生异常都被执行的代码在Delphi 中异常类全部派生自
Exception
&#1048708; Java
Java 使用和C++相同的关键字但是其行为却更接近于Delphi 包括使用finally 关键
字所有采用对象引用模型的语言基本都是如此碎片回收程序的存在限制了finally 关键
字对类的应用这些类不仅占用了内存资源Java 认为所有能产生异常的函数都具有一个正
确的异常子句这个子句告诉Java 哪些异常可能会被产生这个假设十分严格并由编译
器进行检查这是一个非常有用的技术即使这意味着程序员要做更多的工作Java 中的异
常类必须派生自Throwable 类
模板通用程序设计
&#1048708; 特性描述
在不指定某些数据类型的情况下编写函数和类的技术称为通用程序设计Generic
programming 也译为泛型在函数或类被使用的时候特定的数据类型会代替函数或
类中的未指定部分所有情况都在编译器的监管之下不会有任何问题遗留给运行期来决定
模板类的一个典型的例子就是容器类
&#1048708; C++
这三种语言中只有C++具有通用类和函数这些类和函数用Template 关键字表示C++
标准包含了一个巨大的模板类库称为STL 用于支持一些特殊而有用的程序设计功能
&#1048708; Delphi
Delphi 不支持模板容器类通常被创建为TObject 类对象的容器
&#1048708; Java
Java 同样不支持模板你可以使用对象容器或采用其它类似的方法
其它特殊特性
&#1048708; 特性描述
以下是其它一些我谈及的特性它们不是基础特性而且仅为一种语言所特有
&#1048708; C++
我已经提到了多重继承虚基类和模板还有一些另外两种语言所不具有的特性C++
支持操作符重载而Java 中支持方法重载C++还允许程序员重载全局函数你甚至可以
重载类运算符编写可能会在后台被调用的类型转换方法C++的对象模型需要拷贝构造函
数和赋值运算符重载而其它两种语言则不需要因为它们基于对象引用模型
&#1048708; Java
只有Java 在语言中支持多线程对象和方法支持同步机制使用synchronized 关键字
同一个类的两个synchronized 方法不能同时运行要创建一个新的线程只需从Thread 类中
派生新类并覆盖run()方法另一个方法是实现Runnable 接口这是建立多线程applet 的
常用方法我们已经讨论过了碎片回收程序Java 的另一个关键特性是代码兼容性但是
这并不是严格的与语言相关的
&#1048708; Delphi
Delphi 的一些特性包括类引用便利的方法指针这是事件模型的基础特别是属性
属性用来隐藏对数据成员的访问这些访问大多是通过方法进行的属性可以直接映射为对
数据成员的读写操作也可以映射为访问函数即使改变了访问数据成员的方式也不需要
改变调用的代码虽然需要重新编译这使得属性称为了一个强大的封装特性Java 也将
在1.1 版中加入这个特性以支持Java Beans
标准
&#1048708; 特性描述
每个语言都需要有人建立一个标准并检查是否所有的实现都符合这个标准
&#1048708; C++
ANSI/ISO C++标准委员会已经完成了标准化工作大多数编译器编写者都努力遵守这
个标准虽然还有很多的差异存在理论上的发展已基本停止但在实现上新的Borland C++
Builder 虽然并不很成熟但使很多人认识到C++迫切的需要一个可视开发环境同时广
为流行的Visual C++将C++向另一个方向发展起来例如大量使用宏我的意见是每个
语言都有它的开发模型在不适于某种语言的环境下强行使用这种语言是毫无意义的
&#1048708; Delphi
Delphi 是一个私有语言所以没有标准Borland 已经授权给一些OS/2 编译器开发商
但是没有什么效果在每一个新版本的Delphi 中Borland 都扩展了这种语言
&#1048708; Java
Java 也是私有语言并且拥有一个同名的商标但是Sun 更愿意授权给其它编译器开
发商Sun 自己控制着这种语言并且好像并不想为其建立一个官方的标准至少目前如此
Sun 也在极力避免不遵守标准的虚拟机被开发出来
结论语言和开发环境
就像我上面提到过的虽然我尽力做到只比较语言的语法语义特性但在适当的环境中
考察它们是很重要的这些语言为不同的目标开发出来是为了以不同的途径解决不同的问
题的并在不同的开发环境中被应用虽然语言和它们的开发环境体现了彼此的一些特性
但它们是为了满足不同的需要而建立的就像我们在对比这些特性时看到的那样C++的目
标是强大的功能和控制能力代价是复杂性提高Delphi 的目标是在不损失太多功能的情况
下尽可能简单以及可视化编程和同Windows 紧密结合Java 的目标是兼容性和分布式应
用为此不惜牺牲一些运行速度决定这三种语言命运的并不是我这篇文章中所涉及的那些
语言特性Borland 的财政状况Microsoft 对操作系统的控制Sun 在Internet 世界的声望
许多人认为的反微软Web 浏览器和Win32 API 的前景ActiveX 以及Delphi 的
ActiveForms 将扮演的角色这些都是影响你选择的因素往往超过了技术因素例如那
个非常优秀的语言Eiffel Delphi 和Java 都从中吸取了很多灵感没有抢到任何市场份额
虽然它在全世界的许多大学中都十分流行
记住时髦这个词已经在计算机世界占有了前所未有的地位就像用户喜欢使用今
年新版本的软件这大概就是为什么操作系统都以年份命名程序员们也喜欢用最新的程
序设计语言并希望第一个掌握它我们可以说Java 并不是最新的OOP 语言在未来的
几年里一些人会开发出更时髦的语言而其他人则会蜂拥而上全然忘记了这个世界上大
多数程序员还在他们的键盘上敲打着传统的Cobol 语句
作者简介
Marco Cantu 意大利人长期从事Delphi开发及教学工作, DelphiX入门到精通
Delphi 开发人员手册及Essential Pascal 的作者撰写过多本涉及以上谈及
的两到三种语言的书如Object Pascal and C++ 并在美国和其它一些国家发行
他为多家杂志撰写稿件并在他的公司WinTech Italia中进行多项OOP语言和
Windows程序设计的培训他喜欢在国际性会议中发表讲话你可以在以下网址找
到他http://www.macrocantu.com/
Essential Pascal 中译本http://www.marcocantu.com/EPascal/chinese/default.htm
回复

使用道具 举报

发表于 2003-12-5 00:00:00 | 显示全部楼层
不是太懂啊。一个从来没有学过编程的人应该首先学哪个语言呢??
回复

使用道具 举报

阿不 该用户已被删除
发表于 2003-12-5 00:00:00 | 显示全部楼层
顶一下做书签
回复

使用道具 举报

 楼主| 发表于 2003-12-8 00:00:00 | 显示全部楼层
以下是引用zhuce2003在2003-12-5 23:32:28的发言:
不是太懂啊。一个从来没有学过编程的人应该首先学哪个语言呢??


都学basic,我最开始先学的pascal,从来没有学basic,你学编程,先要把语法掌握才行,然后才可以深入学习
回复

使用道具 举报

发表于 2003-12-11 00:00:00 | 显示全部楼层
……对我来说都是天书
争取有空多多向各位大侠学习
回复

使用道具 举报

发表于 2003-12-5 00:00:00 | 显示全部楼层
不是太懂啊。一个从来没有学过编程的人应该首先学哪个语言呢??
回复

使用道具 举报

阿不 该用户已被删除
发表于 2003-12-5 00:00:00 | 显示全部楼层
顶一下做书签
回复

使用道具 举报

 楼主| 发表于 2003-12-8 00:00:00 | 显示全部楼层
以下是引用zhuce2003在2003-12-5 23:32:28的发言:
不是太懂啊。一个从来没有学过编程的人应该首先学哪个语言呢??


都学basic,我最开始先学的pascal,从来没有学basic,你学编程,先要把语法掌握才行,然后才可以深入学习
回复

使用道具 举报

发表于 2003-12-11 00:00:00 | 显示全部楼层
……对我来说都是天书
争取有空多多向各位大侠学习
回复

使用道具 举报

adaiadai 该用户已被删除
发表于 2003-12-30 00:00:00 | 显示全部楼层
这样的比较不错啊!!
回复

使用道具 举报

发表于 2004-2-20 00:00:00 | 显示全部楼层
以下是引用sxm_alice在2003-12-8 8:23:17的发言:
[quote]以下是引用zhuce2003在2003-12-5 23:32:28的发言:
不是太懂啊。一个从来没有学过编程的人应该首先学哪个语言呢??


都学basic,我最开始先学的pascal,从来没有学basic,你学编程,先要把语法掌握才行,然后才可以深入学习
[/quote]
为什么都学basic?斑竹不是“先学的pascal,从来没有学basic”吗?请进一步指教。
回复

使用道具 举报

发表于 2004-2-21 00:00:00 | 显示全部楼层
我是c++程序员,也用vb编了一些软件,但大都是水利工程上需要的(也是自己本质工作的需要),也了解一些其他语言。版主的“面向对象编程语言的比较”一文,不论对于初学编程的人员,还是像我这样曾经编写过几个低水平软件的人员来说,都是很有意义的,应该给于倡导和鼓励。通过多多比较,定位自己所选定的语言,确实是一件好事,以便很多人少走弯路,打消疑虑。
回复

使用道具 举报

钻石 该用户已被删除
发表于 2004-2-26 00:00:00 | 显示全部楼层
谢谢你的分享
回复

使用道具 举报

 楼主| 发表于 2004-3-29 00:00:00 | 显示全部楼层
以下是引用dcyxslgd在2004-2-20 8:56:01的发言:
为什么都学basic?斑竹不是“先学的pascal,从来没有学basic”吗?请进一步指教。


dcyxslgd,对于语言来说基本都相通,除了lisp和prolog这些智能编程的语言。我当初没有学basic也有自己的原因吧,不过现在我的basic也会了,因为在这种环境中,整天接触的不是一个语种,各个语种的语法也都了解了不少,希望你根据自己的喜欢去选择少走弯路
回复

使用道具 举报

ssyann 该用户已被删除
发表于 2004-4-17 00:00:00 | 显示全部楼层
斑竹真强,不只是从事何种工作的,不过就是有点乱。嘿嘿
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Archiver|手机版|小黑屋|网上读书园地

GMT+8, 2024-11-23 02:39 , Processed in 0.274485 second(s), 19 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表