⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 192.txt

📁 文本分类,使用贝叶斯分类系统,训练集和测试集
💻 TXT
📖 第 1 页 / 共 3 页
字号:
  function Date.Day: Integer;
  begin
    Result := dd;
  end;
你可能注意到一些语法上的区别:定义方法使用两个不同的关键字function和procedur
e,没有参数的方法不使用圆括号,方法在类定义中声明,之后再作定义(就像C++中经
常遇到的情况一样)。注意,Pascal使用点运算符,而C++使用作用域操作符(::)。
·注意:访问当前对象。OOP语言的方法与全局函数不同,它包含了一个隐藏参数——一
个指向当前被操作对象的指针或引用。在不同的语言中,这个参数的名字不同,在C++和
Java中是this,在Object Pascal中是self。
构造函数(constructor)
·特性描述:上文所述的类实在太简单了。为了解决对象初始化的问题,我们要为类增
加一个构造函数,这也是改进类所需迈出的第一步。
·C++:在C++以及Java中,构造函数和类具有相同的名字。如果你没有定义构造函数,
编译器会自动为类添加一个默认构造函数。在这两种语言中,你的类可以具有多个构造
函数,这要感谢“方法重载”。
·Java:在Java中,虽然构造函数也被称为初始化函数(initializer),但与C++的构
造函数在使用上没有什么区别。需要注意的是,Java虚拟机负责创建对象,而构造函数
只对创建的对象进行初始化(Object Pascal也有类似的情况)。
·OP:在Object Pascal中,构造函数以一个特殊的关键字——constructor声明。在OP
中没有方法重载(?,没有吗?——译者),不过因为构造函数(在Delphi的书中通常
成为构造器——译者)的名字可以任意指定,所以你可以提供几个名字不同的构造函数
。OP中每个类都有默认的构造函数“Create”,除非你用名字相同而参数不同的构造函
数将其覆盖。这个构造函数继承自一个通用基类,下面我们会提到。
析构函数和finalize()
·特性描述:析构函数扮演了构造函数反面的角色,通常在对象销毁时被调用。如果说
大多数类都需要构造函数,那么只有很少的类需要析构函数。一个析构函数的基本功能
就是释放构造函数(以及对象生存期中的其它方法)分配的资源。这些资源包括内存、
文件、数据库表、Windows句柄,等等。
·C++:C++的析构函数在对象超出作用域时,或者删除动态创建对象时自动被调用。每
个类只能由一个析构函数。
·OP:Object Pascal的析构函数与C++的析构函数类似。Object Pascal使用标准虚拟析
构函数,称为“Destroy”。析构函数通过标准“Free”方法调用。因为所有对象都是动
态创建的,所以你或者对象的属主必须调用对象的析构函数,以释放资源。理论上你可
以定义多个析构函数,不过只有你手动调用析构函数才有些价值(没有什么是自动完成
的)。
·Java:Java没有析构函数。没有引用的对象将被碎片回收程序在后台销毁。在销毁对
象之前,碎片回收程序调用finalize()方法。但是,并没有什么保证这个函数真正被调
用(至少在Java 1.0中时是这样)。因此,如果你需要释放资源,你就要定义一个方法
,并保证它被调用。
类封装(Private和Public)
·特性描述:这三种语言提供了相同的三种访问限定符来提供不同级别的类封装:publ
ic,protected和private。public意味着对于任何类都是可见的,protected意味着对于
派生类可见,private意味着没有外部可见性。但是三种语言的实现细节并不相同。
·C++:在C++中,你可以使用friend关键字跳出类封装。由class关键字声明的类默认可
见性是private,由struct关键字声明的类默认可见性是public。
·OP:在Object Pascal中,private和protected关键字只对在不同单元中的类有作用。
在同一单元(源代码文件)声明的类彼此之间可以自由访问。Delphi还有两个特殊的访
问限定符:published和automated。published将为类的成员建立RTTI(运行期类型信息
),automated用于OLE自动化接口(已废弃——译者)。
·Java:在Java中,一个语法上的区别是每一个类成员都要用访问限定符声明。另一个
实质上的区别是,Java中类成员默认访问限定符是friendly,因此对同一个包(源代码
文件,类似于OP的单元)中的所有类都是可见的。同样,protected关键字表示类成员对
派生类可见,同时也对同一个包中的其它类可见,而private protected才对应于C++中
的protected。
文件、单元和包
·特性描述:这三种语言的一个重要区别是对源代码文件的组织管理。它们都使用文件
作为储存源代码的标准机构(与其它OOP语言如Smalltalk不同),不同的是C++的编译器
并不真正了解文件,而OP和Java则不同,它们使用模块概念来管理文件,虽然各自的名
字不太一样。
·C++:在C++中,程序员们一般把类定义放在头文件中,而把方法实现放入独立的代码
文件。通常这两个文件会具有相同的文件名和不同的扩展名。一个编译单元应该包括它
自己的声明文件及其代码所涉及的类及函数的声明文件。但这仅仅是惯例,编译器并不
强迫这样做。链接器将不得不做更多的工作,因为编译器无法预料一个方法是否在某个
模块中被定义。
·OP:在Object Pascal中,源代码文件被称为单元(unit)。单元被分为接口(inter
face)和实现(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,su
bclassing)、被继承的类(基类,父类,超类)和继承的类(派生类,子类,次类)。

·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或dynamic引入(这两个关键字

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -